Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/16/2022 in all areas

  1. This week we have ProcessWire 3.0.205 on the dev branch. Relative to 3.0.204, this includes 23 new commits including several refactored classes, issue resolutions, several pull requests and various new features. While there's no single major new feature to write a blog post around, there's still a lot here so for full details see the dev branch commit log. This week there's also a new module released in the ListerPro board called PageActionCrawl. This is a ListerPro PageAction module that crawls all pages sent to it. You can use this to crawl your entire site, some portion of pages within it, or even crawl external URLs referenced in URL fields. This is useful for any number of things such as priming caches, finding errors, quality assurance, doing security testing and more. Features include: Supports crawling with GET, POST or HEAD requests. Supports optional query strings and/or URL segments. Reports the HTTP response code and render time for each URL. Highlights error URLs (http code >= 400) in red. Optionally supports crawling of multiple URL variations per page. Supports inclusion of custom POST variables in POST requests. Supports page URLs or URLs stored in FieldtypeURL fields. Supports success and error hooks for custom behaviors on crawled URLs. Speaking of ListerPro actions, I've moved all of the 9 ListerPro action modules into their own new subforum of the ListerPro support board, so if you subscribe to ListerPro be sure to look for the new ListerPro Page Actions board in there. That's also where this new PageActionCrawl module is posted. Thanks for reading and have a great weekend!
    7 points
  2. It is no secret that Wordpress attracs a lot of no-coders and low-coders because of it's available template market. The no-coder buys a template on envato, themeforest, templatemonster, etc. and sells it as a website to the client. Most of the clients don't even know they bought an envato template website because they have no time and no website experience. By the time the client needs to have something changed, the wordpress template limitations won't allow for it and the no-coder is long gone selling a template somewhere else. Sooner a later the client is forced to call for a real coder for the needed level of support. Pagebuilders will attract even more no-coders and low coders. Having followed the Pagebuilder scene in Wordpress with Beaver, Bakery, Brizy, VisualComposer, Elementor, Genesis, Gutenberg, Themify, Divi, Oxygen, GeneratePress .... the list goes on and on. There is almost every month a new Wordpress Pagebuilder on the block. Why spend time in learning the Pagebuilder of the day if you could spend that same time in learning html, js, css and php and never need a Pagebuilder in the first place and give the Client a website that he really deserves: without Template limitations, unused theme functions and without all the Pagebuilder bloated code. Coming to my point: I hope that what is happening in the Wordpress Pagebuilder scene will never happen with future Processwire Pagebuilders.
    5 points
  3. Another example, clients receipts generated by the terminal are sent on real time to the "receipt app" which can be seen there: https://facture.kingspark.fr/ You can see something more than ~4M pages. This following example, is a dashboard for accouting things, a database of 10gb and more than 11M pages: (traduced by on-browser-google-trad)
    4 points
  4. Hi @jsilmarovi You could bootstrap PW instance to your Laravel app https://processwire.com/docs/front-end/include/ and that use PW api to create or edit pages https://processwire-recipes.com/recipes/create-page-via-api/ https://gist.github.com/lokomotivan/e0a20f96b6df02970bccd700a119930e
    4 points
  5. Ryan has already stated lots of times that he is not interested in growing the user group just for the sake of growing it. In other words, it is very low priority for him, as far as I understand it. He is also not interested in page builders as such, but happy to add features to Repeater Matrix that support such use cases whenever he has the time to work on it. I guess that will be the closest to "page building" from Ryan. "Theming" will certainly never be possible with ProcessWire as a core feature as that would be agains its philosophy, wouldn't it? A solo or a team of developers can surely come up with their own theming schema and implement it for themselves but that is a different story, I think.
    3 points
  6. One more possibility: get your non-user pages by path instead of by ID. If you use PagesLoader::getByPath() it should be just as robust as getting by ID because page path history will handle any renaming or moving of pages. And as a bonus the code is more readable because it's more obvious what page is retrieved by '/about-us/sustainability/' than by 24875. $p = $pages->loader()->getByPath('/about-us/sustainability/', ['useHistory' => true]));
    3 points
  7. This last week my wife and daughter took a trip to NYC and it was my daughter's first time there. I was browsing around online looking at things they could do and so I visited the Guggenheim museum website to look into that option... I've always been a fan of the building, a Frank Lloyd Wright masterpiece. In addition to New York, I learned from the website that Guggenheim also has museums in Abu Dhabi, Bilbao and Venice, so I clicked through to view them as well. I really liked the Venice Guggenheim website, which had a much nicer website than the other locations. It was such a nice site that I was curious what they were running, so I viewed the source and... not WordPress (like the others), but ProcessWire. What a nice surprise. Then I was curious about who made such a nice site and there was a credits link in the bottom right corner that says the site was made by basili.co, nice work! It's always fun to come across a ProcessWire powered website randomly like that, and I thought you all would enjoy this one too. This week there are fairly minor updates on the core dev branch. Though the updates include one I've been meaning to do for a long time: improve the API for processing Inputfield forms. Previously there's been no way to check if a form is submitted, short of checking an $input variable yourself. Today I committed an update that adds a $form->isSubmitted() method that solves that, and more. It can identify which form was submitted, which submit button was used, and it also performs additional checks to make sure it's a valid submission before deciding that it's a form worth processing. It improves reliability, accuracy and security. Next week I'll be updating several of the admin forms to use it, among other updates. A few other useful helper methods were added to the Inputfield forms API as well. I realize that these updates may only be of interest to module authors, but I like keep you up-to-date with the week's updates either way. Thanks for reading and have a great weekend!
    2 points
  8. Thx to @gebeer I have now set up my VSCode to format my code in PSR12 on save ? It's very easy to get if you know how and if you have Intelephense installed (which I'd highly recommend). Simply copy that to your user settings.json: // code formatting on save "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "[php]": { "editor.defaultFormatter": "bmewburn.vscode-intelephense-client" },
    2 points
  9. Maybe I'm off base here, but since you say the user is the issue, why not create your own ISAM routine by hooking the registration to it's own domain/database and passing the result to the proper installation login/user.
    2 points
  10. This. And you can have a read on a example I posted recently, I will add you two or three more screenshots of the page tree created by our softwares. Edit: Others examples added to the thread, I will make one day a showcase... but you just have to know that no page are created from the admin, but by API calls. The module used is the one linked by @MarkE and made by @Sebi . Anyway, it let you use the workflow you want, I mean freedom. And also, you can note that it scale pretty well (even if my apps are not so quite optimized, just saying).
    2 points
  11. https://processwire.com/modules/app-api/ ?
    2 points
  12. TLDR: Use custom selectors in page field selector: - check_access=role1|role2 ... - to control who can see results - field=[item.id] - to select on id of repeater item containing the page field. ------------ This module extends the capabilities of selectors specified in the 'input' tab of a page reference field, specifically when that field is part of a set of dependent selectors which may be inside a repeater item. The readme also attempts to bring together various existing documentation regarding the use of dependent page selectors and the enhancements that were provided by various PW versions. See https://github.com/MetaTunes/CustomDependSelects for full readme and to download. Please note that this is an initial alpha release. Please test in your own context thoroughly before using. Also note that PW3.0.200 is required and 3.0.203 is preferred.
    2 points
  13. Over the years, I've experimented with using RepeaterMatrix as the basis of a rich page builder. I've gone through at least a dozen concepts, most of which hit the chopping block due to either being too complex, not well thought out, too clever or too limiting. To my knowledge, the only other CMS that takes the "Builder" approach that I've demonstrated is DjangoCMS (meaning, it has a matrix-like field with depth support). While the "Builder" approach works well, it could be too advanced for some people. Therefore the other approach is the "Classic" approach where you don't deal with containers/rows/columns (which instead is handled by template code), and simply enter the content in the respective field. This is easy to understand, but has drawbacks in terms of flexibility. If it were made to be too flexible, it would become a "God" block which is bad. Then I finally thought of a third approach which is a mix between the Builder and Classic approach. It uses the basic builder blocks, combined with the layout from the matrix item template file. By using the basic builder blocks, you get the plethora of options. It requires an extra page to be created behind the scenes however, but live preview still works. I made a video comparing all the above (10m duration). I want to hear your feedback on this as I am ~75% done with my super module (doing a lot of code and concept cleaning at this point) and want to finish off this portion of it. (note: I'm posting this in the Dev Talk forum since this is a discussion / not support request)
    1 point
  14. hi, just to explain what @iank said, first of all your $page->save($number) couldn't work because what is number, where to save it and so on ? to do it the way you were going to, you would have to write $number = $page->number != '' ? $page->number: 0; echo $number; $number++; echo '<br />new' . $number; $page->of(false); $page->number = $number; $page->save(); and, as you can see @iank solution is faster and, quite often, when coding the shorter, the better ? have a nice day
    1 point
  15. @netcarver please check v1.4.0 ? There was a wrong example in the readme having old RM1 syntax. But I've updated RM2 to use that syntax too!
    1 point
  16. Hey @netcarver sorry for the troubles!! Is the file called migrate.php ? It looks like it should work! The only think that I don't do is strict_types=1 - maybe that causes issues? Don't know anything about that. Do you have tracy installed? Then you can inspect the logs panel and you should see everything that RM did. And you see if it did something, because if there are no changes or your file is not watched then changes will not be applied... Yeah this is part of the MagicPages features introduced 2 weeks ago. It creates fake pages in the trash to make sure it can load those pages on init() and ready() and trigger their init() and ready() methods to attach hooks. I'm not happy with that solution yet and it introduced some problems on some of my projects, so I'll fix this as soon as possible! Meanwhile you could just use an older version: https://github.com/baumrock/RockMigrations/archive/742f1fab8c727b3892835bb43d573e4f5aa7be0d.zip
    1 point
  17. Version 2.0.2 Fix Issue #2 Fix taglist for "Grouped add buttons" Add PW and PHP version requirements Add german translations ... and with hardcoded version number #3
    1 point
  18. I'm also seeing a lot of fake pages in the trash that seem to be generated by RockMigrations, despite my test file having nothing to do with either the pages or fields in the migrations.php file. For example...
    1 point
  19. Version: 1.0.2 Add meta data to podcast model (subscription links) Add example rendering for podcasts and episode lists
    1 point
  20. Hello. I would like to know if I can use ProcessWire just as a background CMS instead of the CMS itself? Let me explain the case to ease the understanding: I have a customer that I developed a website using ProcessWire and a recruitment system thats uses Laravel. To manage contents he uses the ProcessWire Interface, but to manage the recruitment entries, he uses the interface that I developed in Laravel. Customer asked me a way to unite the content management with laravel app to use only one interface. I would like to know if ProcessWire have somekind of API that allows me to manage content outside ProcessWire interface?
    1 point
  21. Why not use a custom page name as a reference/ID across those instances? You could create those "on the fly" when someone is signing-up and therefore that "ID" would be unique. us-[timestamp]-{page->name} eu-[timestamp]-{page->name} Sure... using Page IDs is way easier, yet creating your "own ID" or using a "foreign key" could be an option. Needed this within a product catalogue (not users) but still. It worked out quite well.
    1 point
  22. That's a shame. Maybe an initial release would help ? At least some feedback might be useful.
    1 point
  23. Pages::___save() method has a forceID parameter: * - `forceID` (integer): Use this ID instead of an auto-assigned one (new page) or current ID (existing page). I've never tried to do anything like this, but it seems like this would be a good place to start, e.g. hooking before this method and forcing the ID in case of a new page using the user template. You would still have to figure out some way to share auto-increment ID values between instances ?
    1 point
  24. Hi @DaveP, thanks for the idea. Hadn't thought of that - but I think it will become difficult to pull off, especially if we extend to other regions and have to sync 3 or 4 (or more) installations.
    1 point
  25. A few new additions to this old module, available as of version 1.8.0 (session.txt import) and 1.9.0 (new API methods): There's an option in ProcessLoginHistoryHooks module config to import login history from session.txt. This can be useful when adding this module to a site with existing history, since ProcessWire (by default) collects data about successful/unsuccessful login attempts to said log file. This option is intentionally hidden under collapsed "advanced" fieldset. It's not super well tested yet, could result in a very slow request in case there's a lot of data to import, and in case disk timezone is different than the one in database duplicate records may be created on first run. $this->modules->get('ProcessLoginHistoryHooks')->getUserLoginHistory($user, $start, $limit, $login_was_successful) returns login history data for provided ProcessWire User object. Default values are 0 for "start", 2 for "limit", and 1 for "login_was_successful", which means that by default this method will return latest successful login and the one before that. Return value is always an array; in case there are no results, an empty array is returned. $user->getLoginHistory($start, $limit, $login_was_successful) does the same as previous command for a specific User object. All arguments are optional. This method returns a single timestamp (when limit is 1, or an integer value is provided for the "start" argument and "limit" argument is omitted), an array of login history, or null in case there are no results. By default timestamps for last two successful logins are returned.
    1 point
  26. @regesh Have a look at https://processwire.com/modules/custom-inputfield-dependencies/ You'll have multiple options to configure the visibility of fields and even the possibility to mark them as required if your selector is matching. It adds following options to the fields:
    1 point
  27. Could you pleas tell us why you want to do that to get a better understanding of the context? Also, what do you mean by "a large set of pages"?
    1 point
  28. I'd be very interested in some details and explanations on this ? I've been working with forms quite a bit and sometimes things where a little unclear to be honest. For example sometimes I had to do a $this->trackChange('value') to make my inputfield module save anything. While I found a way to make it work it would be nice to better understand the inner workings of the whole process ?
    1 point
  29. @pwired sure, here you are. site/templates/fields/sections_next.php This file is responsible for outputting rendered HTML for the field called `sections_next`. It's called with the `$value` set to the value to be rendered, which in this case is a field of type PageTableNext. <?php namespace ProcessWire; /** * @global Page $page * @global PageArray $value * @global Field $field * @global Pages $pages * @global Config $config */ ?> <div style="margin:1rem;border:solid 1px yellow; background:#ffffe0;padding: 1rem;"> This is sections_next.php <?php if(!($value instanceof PageArray)) return; foreach($value as $contentElement) echo '<div style="border:solid 1px #fc0;background:#eefff8;padding:1rem;margin:1rem;"> The following is rendered by ' . $contentElement->template->name . '<br />' . $page->renderValue($contentElement, ($field->pathToTemplates ?? '') . $contentElement->template->name) . '</div>'; ?> </div> site/templates/fields/sections/hero.php This file and the one that follow are two example possible section/paragraph/block types. For my proof of concept, I created a "hero" one and a generic "section" one. This hero one crudely renders a big background image with some big text over the top. <?php namespace ProcessWire; $image = $value->background_image; $thumb = $image->size(1920, 700); ?> <div style="background-image:url(<?php echo $thumb->url ?>); padding: 4rem;margin: 0 0 2rem 0;min-height:60vh;"> <p style="color:#fc0; font-size:3rem; font-weight:bold; text-align: center; line-height: 1.4;"> <?php print $value->title; ?> </p> </div> site/templates/fields/sections/section.php The 'section' type has a body field and a select field letting the user choose Blue/Mauve/None for the background colour. <?php namespace ProcessWire; // here, $page is the main page tht was requested; $value is the Page object being rendered, the 'section'. ?> <?php $map = ['Blue' => '#0284ea', 'Mauve' => '#f0ddff', 'None' => 'transparent']; $selected = $value->background_colour->title; $bg = $map[$selected ?? 'None']; ?> <div style="border:solid 1px #cf0;background:<?php echo $bg; ?>; padding:1rem;margin:1rem;">This is section.php, rendering <code>$value</code> <h2>title: <?php print $value->title ?></h2> <p>colour: <?php print $value->background_colour->title ?></p> body: <?php print $value->body ?> </div> Other files Now the instructions for PageTableNext (ptn) tell you to copy some other files into your templates dir, but I've not figured out why! e.g. The instructions made me copy a file from the module to site/templates/PageTableNext/ptn.php, however I put exit() at the top of that file to test whether it was ever used and I've not found it to be doing anything, so I don't understand that! Here's my demo page content: In the editor it looks like this: ➊ shows the three blocks/sections/... that I've added (with the buttons at ➌). I clicked the arrow to 'open' the third section and you can see it at ➋ rendered using just the site/templates/fields/sections/section.php file. The UI is pretty nice; you can edit each section, move them around etc. Oh, one other thing, in the main page template (e.g. basic-page.php) you need to render the field that contains all the blocks/sections/etc. like so: <?php // If using 'delayed' output: $content = $page->render->sections_next; // If using 'direct' output echo $page->render->sections_next; One interesting thing is that if you use delayed output then your site/template/{page-type-name}.php needs to populate $content (or whatever vars you use in _main.php). However, the field templates all just use echo/print because they are rendered with output buffering capture. Hope this helps! It might help me too when I come to actually make a site with PW instead of just playing!
    1 point
  30. I've found a nice solution using PageTableNext. - I can define different section(block/paragraph...) types with appropriate fields, e.g. hero, text with image on right, ... I can create templates for all these. - I can add/delete/reorder/edit etc. these to a page and see previews in-editor. Thanks for the help.
    1 point
  31. Look at this example. Its made with the old version of RestAPI first made by @thomasaull years ago. To get the context, you can navigate to https://kingspark.fr and https://valideur.mykingspark.fr . I am speaking about a system which give the possibility to some of our client use their mobile or a barcode scanner device to give "free of charge parking" of their customer. Its composed with custom hardware, software and devices or mobile apps (you see it on GooglePlay). Image #1: List of Parkings // Image #2: The custom made SAGAS Terminal // Image 3: A configured User / Device available for registration and use. On the first picture, you can see a list of "Parkings", and some can have the "Valideur" functionality. We can configure attached devices and some users with specific role to get access for registration. And then, imagine the following. A customer land on the parking, grab a ticket and go to their rendezvous At the end, the guy in the office use his "Barcode Scanner" to "validate" the ticket of the customer; This mean that the customer will not pay anything when landing on the terminal to exit the parking, and when he will present the ticket on the barcode-reader installed on the terminal (the "black hole" you can see on the center in the picture), it will be recognized by another software and thought a call on ProcessWire Rest API backend. I made you two screencasts, the first is the software which once installed and registered, get the quota (number of validation available) from the user assigned to the license-code, and the second is my mobile which get notification sent from ProcessWire (by this module) from a monitoring system to get real-time information on registration. If you have any question, do not hesitate. There a more example, but you should get the whole idea ?
    1 point
  32. Nice to have this conversation going on) Thanks @Jonathan Lahijani! The 1st approach There is probably a room for each of the approaches. For now I am always using the 2nd one. It is the easiest for non-technical people and I have them in the admin. I do not think that I will ever use the 1st approach as it is. It is too complicated and too closely coupled with the markup IMHO. Not unless we make it more visual. To do it, we need at least 1, 2 and 9 from this list. The 2nd approach I can see how the 2nd approach could be made more configurable. You said earlier you're using Mystique for the options. I would've build option sets for different option groups: Оne for the section, dealing with section background, margins, width and so on. One for the grid, making columns proportions adjustable (50/50, 30/70, 33/33/33, 25/25/50 and so on). That option set should be limited by the pre-defined number of columns for block, so you wouldn't have 33/33/33 for a block that only should be displayed in 2 columns grid. Option sets for image and text (for the example in the video). The easiest way to implement those option sets is having them in separate Mystique fields. But they also probably could be merged into one general options field using this (hope I understood it right, didn't try it). Using separate fields would bring the benefit of positioning options next to corresponding items (like putting image options next to image field). I understand that this could be a lot of work to configure those option sets, but that could pay off in the long run. The main downside to 2nd approach is that you cannot easily and visually change elements' position/order. Like making image+text field a field+image. Or adding another column making it text+image+text. The 3rd approach I like the idea of using the 3rd approach, but I do not like the implementation. It indeed looks kind of hacky. I would stay closer to RM basic functionality, though extend it. I think that there could be a neat way to make it if @ryanwould help us here. We would need to implement no. 1 (and 2)))) from this list (Make possible to define allowed children for the matrix types.) This would make 1s approach more solid, but also help us with the third. So we would only allow image and text block under image+text. We would need to make possible creating groups of blocks from add block button. So when we add image+text block image and text blocks are automatically created under it. Might be already possible with hooks. We need to think what happens when we move one of the child blocks somewhere else, so there would be only text under image+text and no text. Or make it impossible to move them out of that nesting. Or teach our content managers to not do it (worst scenario)) Well, lots of hacks needed too) But at least the text and image blocks are under the parent block and are manageable the same way as others. --- There are other possible approaches. Probably Johnathan already thought/tried them, but putting them here for more alternatives. The 1+3 approach Let's have only general section block with options (no rows and columns) and content blocks. Content blocks can (but not should) go under section. If they are NOT under section, they display as full width. If there are more than 1 content blocks under section, they are displayed in columns. If you add 4 - there are 4 columns. Widths are adjustable on the content block label. If there are more than 100% of total width, they are displayed in 2 rows. Still we need no. 1 and 2 from this list to not allow content blocks be nested under each other. The Repeater/RM inside RM approach The name says it. Image and text blocks are inside of a RM nested inside Image+text field. Lots of extra fields, lots of configs, but I do it sometimes.
    1 point
  33. It depends on whether you are talking about 'autoload' modules or not. If the dependent module is 'autoload' and the dependency module isn't, then your dependent module can just load the dependency in it's init() or ready(), like this: public function init() { $dependency = $this->modules->get('YourDependencyModule'); } If the dependency module is 'autoload' and the dependent module isn't, then then dependent module can safely assume the dependency is already loaded. If both of them are 'autoload' then you don't necessarily know which will get loaded first. But by the time either module's ready() function is called, you know that both have been loaded: public function ready() { // safe to assume all autoload modules are loaded and have had their init() called } If the dependent actually extends the dependency (like one class extending another), or has code that needs stuff defined from the dependency before PHP will even parse it, then you need the dependency to have been included as a file first (like you'd expect anywhere else in PHP). As long as you reference the dependency class name in some form, it should trigger PW's class loader to find and include the file. Something like a "Dependent extends Dependency" class declaration should do that, as should a function call like: Dependency::getModuleInfo(). If you find that still doesn't do it, you can also try including it manually. But use the "once" version, i.e. include_once($file); or require_once($file). However, I don't think you'll have to go as far as doing this manual inclusion. Install Dependency Because load order dependencies don't usually require any intervention on your part, we usually think of module dependencies as being install related. ProcessWire has some things to help you in this area. You can specify this in your getModuleInfo() method: static public function getModuleInfo() { return array( 'title' => 'Module title', 'summary' => 'What the module does', 'version' => 100, 'autoload' => true, 'singular' => true, 'requires' => array('YourDependencyModule') // SEE THIS LINE } Here are all the details about module dependencies.
    1 point
×
×
  • Create New...