Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 04/05/2023 in all areas

  1. So... there are more videos in german available. I recently found these from @hheyne. https://www.youtube.com/@henningheyne/videos They will help a lot to get into the topic of ProcessWire even more. The easiest way to get a basic understanding of PHP - at least in my opinion and for a good start with ProcessWire - the official tutorials are really good at this. They tell you how to work with ProcessWire and the absolute basics you need. You can achieve a lot with just that. Maybe not an eCommerce/shop system or similar, but a blog, portfolio, and such are absolutely possible. Maybe look into the existing site profiles to see how others do things. There are some interesting ones there. https://processwire.com/docs/tutorials/ https://processwire.com/modules/category/site-profile/ You really should play with these and give them a try. In terms of all the frontend stuff... that's a bit harder. Even though Bootstrap and UIKIT are nice frameworks, you should know at least the basics of HTML and CSS. Which brings us back to the beginning unfortunately. The way I learned most of the stuff was by playing with existing themes and templates - that's decades ago. There are tons of free themes/templates out there you could deconstruct. https://styleshout.com/ https://html5up.net There are good tutorials from Kevin Powell, WebDevSimplified, developedbyed, and many more on YouTube. Maybe give them a try.
    3 points
  2. Hello All, just want to feedback in this thread about my personal start with PW and my progress: I watched the video series of Jonathan Lahijani about WP vs. PW and got very excited. Found a german yt playlist of @LeonidLezner with some infos to start with. After these two series, understood the main concept and advantages BUT, also understood that there is a lot to learn about PHP and CSS coding to get into PW. It's not just working in the nice PW backend... ? This topic is a bit kind of "under-represented" in the Getting started intros. This is definitly not like WP... - it's way better, but also way more coding itself! So, where is a good starting point to get in this PHP and CSS topics in connection with PW dev? I also did the Beginners Guide of Francesco Schwarz, but there is not too much about it in this one... Great thanks for help Daniel
    2 points
  3. Just posting this here as I raised an issue some time ago about TextformatterHannaCode module, which has not been responded to or addressed (see https://processwire.com/talk/topic/3745-hanna-code/page/18/?tab=comments#comment-217245 and https://github.com/ryancramerdesign/ProcessHannaCode/issues/26). I have also recently raised a PR (https://github.com/ryancramerdesign/ProcessHannaCode/pull/27) to fix it. Essentially the problem is that, if you have a PHP Hanna Code which is namespaced (ProcessWire), then the module will remove the namespace (irritating in itself), but also (and maybe more seriously) it will omit the line if(!defined("PROCESSWIRE")) die("no direct access"); which is potentially a security weakness. The PR is a simple one-word fix.
    2 points
  4. I think that is the simplest and cleanest approach. It's possible to spin up multiple databases for one project (https://stackoverflow.com/questions/49785023/how-can-i-create-and-load-a-second-database-in-ddev) but as long as you don't need to have both projects talk to each other I think having them isolated would be the way to go. Just curious: Did you also find processwire.rocks or did that not pop up in your search? Especially the video about RockFrontend could be very interesting for you. I second that recommendation. Having a css framework has helped me a lot to get things done (and work ? ). I'm a huge fan of UIkit and especially in combination with RockFrontend it's a joy to use. I'd be curious in why you switch to bootstrap @szabesz? I've been looking into Bootstrap recently as there is a lot bigger ecosystem around bootstrap. There are so many great and free templates for bootstrap, but none for uikit. Also their efforts on using css variables is very interesting! I'm just a little afraid of the switch. RockFrontend + Less + UIkit work so well and I usually have all the tools that I need and even the awesome UIkit Javascript Microframework is so nice (https://github.com/uikit/uikit-site/blob/feature/js-utils/docs/pages/javascript-utilities.md) that I'm afraid I'd be missing something on bootstrap ?
    2 points
  5. We're looking for someone to take over a ProcessWire site. I will leave the agency I'm currently working for, and since I was the only PW-developer there, we can't guarantee a professional maintenance anymore. Some information: Site is multilingual, 4 languages Pro modules: FormBuilder, Lister and ProFields Current version is 3.0.210 and was launched 5 years ago. The site makes heavy use of FormBuilder. The data is saved to Google Sheet. That works smooth as silk, but sometimes the client needs a helping hand with config (basically, there is a master form which they always clone, and then change some basic stuff). This Google Sheet has to be moved to another account. There is nothing overly complex about this site. There are a few protected pages. I have written a big manual for the client, i.e. tips about the WYSIWYG editor, recommended image sizes, FormBuilder gotchas, how and where to edit categories (related pages) etc. To be honest, I don't expect a big number of new feature requests in the near-term future. We just want to make sure they know who to call, if there's any questions. However, they mentioned that they want a rehaul of the homepage (they switched hosting recently and bought a new domain). If you're interested, write me a PM.
    2 points
  6. Great! Thanks guys for the starting points! This brings me to another ddev question: When i am browsing through these different profiles to figure things out, do i need to spin up a whole new ddev config for each PW instance or can i do multiple subdomains with each one project in it. But then i would need also different db's - from the first hours of playing with these setup it's only one db in one ddev config, correct? So i will do one ddev config for every project/profile?
    2 points
  7. After all the research I have done on how we can train chatGPT specifically for ProcessWIre, I came to realize that it knows already knows PW and its API quite well. I experimented with prompts to make GPT-4 into a PW specialist. This is what I came up with and what seems to work really well: This primes GPT-4 and brings really good results when asking further questions. This example shows that it knows a lot about the API in detail: Q: Are you aware of the ProcessPageClone class and its methods? Not bad at all ? What I'm still having difficulties with is prompting copilot, tabnine or codeium to give me PW specific code. But thats a different story...
    2 points
  8. Hi @bernhard I'm trying to include custom roles, permissions and access via the migrate() method array setup. Looking at the source this *seems* like it should work, but for some reason I get an error: Method RockMigrations::setRolePermissions does not exist or is not callable in this context $rm->migrate([ "roles" => [ 'copy_editor' => [ 'permissions' => [ 'page-view', 'page-edit', 'page-delete', 'page-edit-front', 'page-edit-recent', 'page-move', 'page-sort', 'comments-manager', 'profile-edit', ], 'access' => [ 'home' => [ 'view', ], ], ], 'layout_editor' => [ 'permissions' => [ 'page-view', 'page-edit', 'page-delete', 'page-edit-recent', 'page-move', 'page-sort', 'page-template', 'logs-view', 'profile-edit', ], 'access' => [ 'home' => [ 'view', 'edit', ], ], ], ], ]); // I include fields and templates and other things later - I will likely move roles AFTER templates once this is working. Is there something I am missing here?
    1 point
  9. @ngrmm Ok, I see the issue now. I have never used the generated markup (embed option D), so I haven't run into this issue yet. The problem is the new bypass permission added in 2.0.0. Any user with this permission (the superuser has all permissions) will not see the captcha, the inputfield doesn't output any markup in this case. When you're generating the form builder markup, FormBuilder just renders the form with the current settings and outputs the resulting markup as a template (with some adjustments) as far as I can tell. But you're logged in while doing this, so the resulting markup will not include the hCaptcha code. Not sure if I can solve this from within the module. I think you're going to have to manually add the hCaptcha markup to the generated template. Place this in the generated markup in the place where the hCaptcha is supposed to go: <?= $form->getChildByName('hcaptcha')->render(); ?> Replace hcaptcha with the name of the hCaptcha field in your form. If this doesn't match the custom markup you need for this form, embed the form using one of the other embed methods, open the page with the form as the guest user and copy the generated markup from there. Then you can modify it as required. Or just include the inputfield manually.
    1 point
  10. @Robin SThanks a lot, that was the solution! For whatever reason I had activated access control for that field...
    1 point
  11. Got it $orderItem->padloper_order_line_item
    1 point
  12. Hi Friends, yes night a had a little doubt when i was browsing some profiles (uikit3 i started with)... will i ever get into this, or just stop right away... ? BUT Let's try step by step... I mean, i come from a Linux server background (server, and cloud maintaining). So a every day maxim to me is KISS (keep it simple stupid!)... But when i watched all this weaving together HTML, PHP and CSS i was overwhelmed... Today i started the tutorial series of Henning to get in the basics and a lot of things become very clear! I hope i can get around coding all the CSS stuff... jut use a nice template and adjust... hopefully... ? Small anecdote: When setting up vim plugins for the PW dev i smiled a little about the commentary plugin... "why do i ever need a plugin to do comments?" - then i saw all the different commenting styles in these files... :))) How do you solve the problem of filetypes in vim? I can either set it to html or php, but i need both... in ultisnips i can add filetypes together, the works like a charm, but otherwise? Do you set it to php or html?
    1 point
  13. Mostly because of that. For example I wanted to use https://bootstrap-table.com/ and some other smaller interface elements, as well. Also, its docs are better than the UIKit's, I think. While Bootstrap 4 was not something I considered moving to, Bootstrap 5 has matured a lot, so that is why I started to looking into using it in the first place. Also, Bootstrap is more of a "low level LEGO" solution compared to UIKit, which can be a good thing at times. (For this reason, it is easier for beginners to start with UIKit 3, I believe.) I am also a fan of Unpoly and jQuery so I do not need yet another similar helper. uikit.min.js is 139Kb while the full version of jQuery is 90Kb so it looks like the UIKit developers had to (at least partially) reinvent the wheel just to get rid of jQuery. (I have never used UIkit.util too much, so I cannot say for sure, but looking at the docs they have overlapping features.) Also, Unpoly and jQuery has overlapping features, too, but I am still not ashamed of using jQuery even in 2023 :) I'm mostly using it for its powerful "selecting" capabilities, which are concise and have matured throughout the years.
    1 point
  14. @Sava Hi my pleasure and very glad to know you manage to do what you needed ? have a nice day
    1 point
  15. Additional info: with above solution, chinese characters are preserved as UTF8 in page names. But all other UTF8 characters in other languages do not get translated with pageNameTranslate like they would if the site didn't have $config->pageNameCharset = 'UTF8'; That is undesirable because for example, german umlauts now get translated from ä to a instead of ae. If setting $config->pageNameCharset = 'UTF8' is active, the pageNameTranslate sanitizer ignores the character map, that we can usually set in the module settings for InputfieldPageName. Actually, that editable character map is no longer available when $config->pageNameCharset = 'UTF8'. To circumvent this issue, I manually replace all characters before passing them to sanitizer pageNameTranslate I wrote a function that takes the default character map for replacements from InputfieldPageName::$defaultReplacements, adds custom characters and then performs string replacements based on the character map: /** * replaces characters in a string with characters from a custom character map * needed because Sanitizer::pageNameTranslate() doesn't take into account the character map defined in InputfieldPageName * because the site uses $config->pageNameCharset = 'UTF8'; * used in the Pages::saveReady hook in ready.php * * @param string $string * @return string */ public function replaceCustomCharacters($string) { // take default character map from InputfieldPageName class $defaultChars = InputfieldPageName::$defaultReplacements; // add additional characters $allChars = array_merge($defaultChars, [ 'ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue', 'ß' => 'ss', ]); // replace all characters from map $allChars in $string $string = str_replace(array_keys($allChars), array_values($allChars), mb_strtolower($string)); return $string; } My final saveReady hook now looks like this: /** * only use UTF-8 page names for defined languages */ $wire->addHookBefore('Pages::saveReady', function($event) { /** @var Page $page */ $page = $event->arguments(0); if($page->template->name == 'admin') return; // exclude admin pages if($page->rootParent->id === 2) return; // exculde pages under admin tree (e.g. media manager pages) $languages = $event->wire('languages'); /** @var Sanitizer $sanitizer */ $sanitizer = $event->wire('sanitizer'); $utf8Languages = ['cn']; // Add more languages as needed foreach ($languages as $language) { if ($language->isDefault()) continue; $langName = $language->name; $translatedTitle = $page->getLanguageValue($language, 'title'); if (in_array($langName, $utf8Languages)) { $pageName = $sanitizer->pageNameUTF8($translatedTitle); } else { $pageName = $sanitizer->pageNameTranslate(wire('site')->replaceCustomCharacters($translatedTitle)); } $page->setLanguageValue($language, 'name', $pageName); } }); Note that my replacement function lives in a custom Site module that is made available to the API as wire('site'). All in all there is a lot to consider with UTF8 page names activated. I wish PW would make life easier here. Just the other day when I played around with GPT-4 and asked it how we could solve that problem, it started to halluzinate and proposed that the only thing I had to do was setting utf8PageNames property per language like in this dummy code: $lang = $languages->get('cn); $lang->utf8PageNames = true; $lang->save(); In reality the Language object does not have such a property. But I think, this would be a great enhancement and would allow setting page name behaviour based on each language and not globally only, like it is now. Will open a feature request.
    1 point
  16. Usually such things are the result of being logged in (probably as superuser) in one browser and logged out in the other browser. It looks like that's the case in your screenshots because I can see the Tracy debug bar in one screenshot and not in the other. So probably the difference is due to some access issue, where superuser has access to something that guests do not.
    1 point
  17. Hello Daniel and welcome to ProcessWire, If you want to ease your way into working with CSS, then I recommend either using UIkit 3 or Bootstrap 5. Both have its pros and cons, so you need to look into both to decide which one you prefer. For example, I started with UIkit 3 but nowadays I prefer Bootstrap 5. So preferences can change, too :) A lot of PW devs also like Tailwind CSS, for example, but there are loads of others, of course, for example: https://github.com/troxler/awesome-css-frameworks As for PHP, it's hard to recommend something which stands out of the crowd, but you might find useful tutorials here: https://hackr.io/tutorials/learn-php?sort=upvotes&type_tags[]=1 Just avoid old PHP tutorials as they probably teach deprecated PHP stuff. Stick to PHP 8.x and up. Hope this helps. Happy coding! ps: use the Google site search to search on this forum and/or in the PW blog. You'll get quick results that way.
    1 point
  18. @MoritzLost Are you sure you're not logged in, and your guest user doesn't have the permission to bypass the captcha? yes Maybe the form was cached while you viewed it as the admin, and the guest user is seeing the cached output without the captcha input? I guess that is not the case What happens if you submit the form (as the guest user) while the captcha is not visible - do you get an error or does the submission succeed? It gives me this Error: [fieldname] - Captcha response is missing. Please fill out the captcha and try again. Depending on selected strength and hCaptcha subscription (if any), the script may not always show a visible captcha if it's confident you're a real user. Try reloading the page with the DevTools open - is the hCaptcha script being loaded? I was testing it always with devtools open with reset-cache-mode active If so, maybe it's just using a hidden captcha. If not, the inputfield is probably not included at all, then it's probably an issue with your template. Can you post your form builder template? Depending on how your template is built, you might need to include the hCaptcha inputfield manually. Maybe you could try it yourself on a Test-PW-Installation. Just generate a FormBuilder form with simple text fields and a hcaptcha field and try out embed-option D. Generate a copy markup of the form via FormBuilder. PW generates a copy here: /site/assets/cache/FormBuilder/ After copying it to /site/templates/FormBuilder/ the hcaptcha-field won't show up
    1 point
  19. Would like to spend you a ? / ? or ☕ - Is there a way to support you and your module development. Cheers!
    1 point
  20. OK - this kind of works: In my template I've included the Cloudflare script (and added their end point to the content security policy). Then I'm injecting a placeholder into the form: $comments_form= $page->comments->renderForm(array( 'requireHoneypotField' => 'email2' )); // add a div with class="cf-turnstil" to the form - this gets replaced with a token (after a successful challenge) $cft_tag='<div class="cf-turnstile" data-sitekey="yourturnstilesitekey"></div>'; $comments_form=str_replace("CommentForm' method='post'>","CommentForm' method='post'>$cft_tag", $comments_form); echo $comments_form; Cloudflare replaces that with a token if they think you're not a bot. Then in init.php (not _init.php) I'm hooking into ProcessPageVIew $this->addHookBefore('ProcessPageView::execute', function(HookEvent $event) { if(wire('input')->post('CommentForm_submit')){ // get the Cloudflare token. $cf_token=wire('input')->post('cf-turnstile-response'); // and send it to siteverify $postdata = http_build_query( array( 'secret' => 'yoursupersecretcloudflaresecretkey', 'response' => $cf_token ) ); $opts = array('http' => array( 'method' => 'POST', 'header' => 'Content-Type: application/x-www-form-urlencoded', 'content' => $postdata ) ); $context = stream_context_create($opts); $api_json_response = file_get_contents('https://challenges.cloudflare.com/turnstile/v0/siteverify', false, $context); if($api_json_response ){ // check result and redirect if failed. $result=json_decode($api_json_response,TRUE); if(!($result['success'])){ // die or redirect or whaterver you fancy. // print_r($result); // die("Failed verification."); wire('session')->redirect('/some-help-page-or-something/'); } }else{ // die or redirect or whaterver you fancy. die("No response from verification server."); } } }); If we have a comment that's been submitted then I check the token with Cloudflare. If it fails we can redirect or die or something - it'd be nice to fail a bit more gracefully. No idea how well this will deal with spam and I think I'll need to do some user testing but I think it might be useful.
    1 point
  21. Hi @alexm, Yes it does. But that's because at that point it is dealing with an order session, so it doesn't know what the order page is. Hence, the order page is retrieved from the session and passed to it. In your case, since you are creating a dashboard, this is decoupled from any session and you can just retrieve any order you want directly (using their ID). Been there, done that...?. Naah, you are good. NP. Thanks for the offer. I am currently favouring video docs. Been working on this (slow though!) and hope to start releasing soon (although tempted to ask chatGPT do it for me! ?)
    1 point
  22. I've recently bought a new Mac and had to setup ddev on my own the very first time ? Everything went smoothly, but I switched from docker desktop to colima as recommended in the docs and have one tip I want to share: Colima is more lightweight than docker desktop but has one drawback, which - with my idea - is actually now also a benefit in my opinion ? The problem is that there is no easy way to start colima automatically on startup. There are options but I found them a little complicated (maybe because I'm a mac noob). My solution is very simple: I've just added "colima start" to my ddev alias that I use to start any ddev project anyhow. So there's no extra steps needed and if colima is already running, that I just get a message that it is already running. Nice. That also has the benefit that I start colima only when I need it and otherwise it will not need any resources. Here are the aliases that I'm using: # ddev aliases alias ddc='ddev config --php-version "8.1" --webserver-type "apache-fpm"' alias ddcm='ddev config --php-version "8.1" --database "mysql:8.0" --webserver-type "apache-fpm"' alias dds='ddev ssh' #alias dd='ddev start && ddev launch && ddev auth ssh -d ~/.ssh/ddev' alias dd='colima start && ddev start && ddev launch && ddev auth ssh' alias ddm='ddev launch -m' # launch mailhog alias ddp='ddev poweroff'
    1 point
  23. Great to hear that @rastographics ? I think every second invested in getting DDEV to run properly is well worth it! I could not be happier with my dev setup and I hope you will be too ? Just curious: What does that mean in ms per pageload in the tracy debug bar?
    1 point
  24. The problem: Synchronizing fields and/or templates made on the dev server with the live server is cumbersome. At the same time, there is no version control of fields and templates, which some folks (including myself) see as a disadvantage of ProcessWire. A way to have version control to track changes and replicate automatically would be desirable. There is the template and fields export feature in ProcessWire which has said for ages that this is only a beta version, although I have used it many times without any problems. However, even with this method, it is very cumbersome to reconcile changes between dev and live. You have to remember which fields / templates you created and select them, then copy and paste them on the dev server. This is a manual, cumbersome and time consuming process. Existing solutions: For this reason, several solutions have been developed such as: Migrations by @LostKobrakai https://processwire.com/talk/topic/14603-rocksvn-brings-version-control-to-your-fields-templates/ ProcessWires Template's and field's export function https://processwire.com/modules/rock-migrations/ https://processwire.com/talk/topic/25307-oh-no-not-another-migration-module/ https://processwire.com/modules/auto-export-templates-and-fields/ Other systems like Laravel, Craft, Kirby and Statamic use configuration files (migrations, YAML) to manage fields / templates, which allow to create a state of fields / templates. Since the configuration is done in a file, you can of course manage it with git (or other vcs). By configuring in a file, it is also possible to automatically execute these migrations during a git push through different deploy pipelines like github actions, buddy, bitbucket pipelines and thus you have the desired state on the desired server. Where to go from here? In another post @bernhard showcased a prototype, that uses a YAML-file to create and manage fields / templates in ProcessWire. At the same time he showcased a YAML recorder which writes all changes that are made to templates and fields into a YAML file, which looks very promising. I think a combination of a recorder and a YAML config file would be a optimal solution, at least for me. What format to use for such a configuration file was and has also to be discussed: Update 30th September 2022: Until we might have a native method for migrations, I encourage you to checkout the great RockMigrations module. With the module you can have one or multiple migration files, that handle all the stuff mentioned above, like adding fields, adding templates, creating pages with content and setting roles. As the migrations are file-based they are also version-controllable. This makes it easy to work on a feature in a different branch which requires to have other fields/template than in the main branch. Now you can switch between branches and always have the required fields and templates. This is a huge time and workflow improvement. @bernhard steadily improves his module, and me and other contributors try to enhance it, or give feedback.
    1 point
  25. I've been interested in sharing my setup since it's radically changed over the last year for the better. Wish I could open the repo for the code of my flagship project, but it's the site for the company I work for and isn't mine, www.renovaenergy.com Local Dev: Code editor is Sublime Text tuned for my preferences/workflow. OS is Ubuntu Linux, will probably distro-hop at some point like Linux users do. Environment is provided by Devilbox, which I can't recommend enough. It's a fast (mostly) pre-configured yet customizable Docker tool with outstanding documentation. A ProcessWire ready container is available. CSS/JS compiled by Gulp/Babel/Browserify for local dev and production builds. ES6 modules. Zero frameworks, no jQuery. Focus on lightweight JS and code splitting for better load times. CSS is compiled and split into separate files by media queries which are loaded by browsers on demand based on screen size. Currently building out website unit/integration tests using Codeception. This is becoming increasingly necessary as the site becomes more complex. Firefox Developer Edition Tilix terminal emulator, Quake mode is awesome Cacher stores code/scripts/configs in the cloud for easy sharing across machines. IDE integration is solid Meld for fast diffs WakaTime because who doesn't like programming metrics for yourself? DevDocs but locally in a Nativefier app. REQUEST: Star ProcessWire on Github. If a project has 7k+ stars it is a candidate to have it's documentation added to DevDocs. Production: Code editor is Vim on server Deployment is via Git. Local repositories have a secondary remote that pushes code to production via a bare GIT repo which updates assets on the server using hooks. Access to server via SSH only. Changes to files only made locally and pushed. Hosting by DigitalOcean with servers custom built from OS up for performance/security. Custom PageSpeed module implementation. Automatic image conversion to webp, file system asset caching, code inlining, delivery optimization, cache control, etc. Driven down TTFB <=500ms on most pages with load times around 2 seconds sometimes less if I'm lucky haha StatusCake monitors uptime, automated speed tests, server resources, and HTTPS cert checking. PagerDuty is integrated with StatusCake so issues like servers going down, server resources (ram/disk/memory) low, and whatever else get notifications on all your devices. 7G Firewall rules are added to the PW .htaccess file to block a ton of bots and malicious automated page visits. Highly recommended. Mailgun for transactional email ProcessWire Modules & Features: Modules (most used): CronjobDatabaseBackup, ProFields, Fluency, ImageBlurHash, MarkupSitemap, PageListShowPageId, ProDevTools, TracyDebugger, ListerPro, ProDrafts Template cache. We used ProCache initially but saw some redundancies/conflicts between it and PageSpeed tools on the server. Would absolutely recommend ProCache if your hosting environment isn't self-managed. All configurations are saved in .env files which are unique to local/staging/production environments with contents stored as secure notes in our password manager. This is achieved using the phpdotenv module loaded on boot in config.php where sensitive configurations and environment-dependent values are made securely available application-wide. Extensive use of ProcessWire image resizing and responsive srcset images in HTML for better performance across devices. URL Hooks - Use case- We rolled out a Web API so external platforms can make RESTful JSON requests to the site at dedicated endpoints. The syntax resembles application frameworks which made development really enjoyable and productive. The code is organized separately from the templates directory and allowed for clean separation of responsibilities without dummy pages or having to enable URL segments on the root page. Also allowed for easily building pure endpoints to receive form submissions. Page Classes - My usage -This was a gamechanger. Removing business logic from templates (only loops, variables, and if statements allowed) and using an OOP approach has been fantastic. Not sure if many people are using this but it's made the code much more DRY, predictable, and well organized. Implementing custom rendering methods in DefaultPage allowed for easily "componentizing" of common elements (video galleries, page previews, forms, etc) so that they are rendered from one source. Helped achieve no HTML in PHP and no PHP in HMTL (with the exceptions above). Also allows for using things like PHP Traits to share behavior between specific Page Classes. I completely fell in love all over again with PW over this and now I couldn't live without it. This literally restructured the entire site for the better. Probably other stuff but this post is too long anyway haha.
    1 point
  26. Probably my method is in the dinosaur category, but it still works without spending too much time on migrating a database: If I do not mix up production with local then it is fool proof. It takes less than 15 secs from start to finish to clone a small database including all the keystrokes I have to perform at the beginning. Sure, it is the other way round regarding migrating, but for a one man show it is not a big deal. When modifying settings in production, I sometimes have to do the cloning more than once but since the whole process is so fast, for me it is a non-issue. "I am still waiting" for an official automated migrating solution included in the ProcessWire core :P
    1 point
  27. And here comes the first talking point I'd like to open... Ryan in his introductory article did not mention whether there is a significant difference between "DefaultPage as a direct subclass" of Page class and "other subclasses of DefaultPage". He also did not mention anything about the recommended way of implementing our own custom "initialization" method for the object, in case we need to perform such a thing. EDIT on 2021-03-28 starts ------------------------------ Taking a look at wire/core/Templates.php it is the getPageClass() method which determines the class of a page. Here, $corePageClass = __NAMESPACE__ . "\\Page"; is used to set ProcessWire\\Page as expected, except when there is a custom page class being used. Then, PW checks if a page class has been set "in the admin" and – if it is valid to use it – then uses that one instead. If no valid custom page class has been found so far, then PW looks for a valid custom page class supported by the new technique of PW 3.0.152+ (that is: extending it in our own client code) and this is where the class name ProcessWire\\DefaultPage is hardcoded into PW like this: $defaultPageClass = __NAMESPACE__ . "\\DefaultPage";. If this class is used/exits as a custom page class, then it is set to take over the pace of the core Page class, like this: $this->pageClassNames[0] = $defaultPageClass; and afterwards: $pageClass = $this->pageClassNames[0]; So my understanding is that by using the name DefaultPage to extend Page, one can "ask" ProcessWire to use it as the bases of almost all page objects, except for users, roles and permissions which are treated differently. Taking advantage of the possibility of using DefaultPage is optional of course, one can just simply extend Page by using any other arbitrary names, but the string literal DefaultPage named subclass is treated as the new core class in case one needs to add some custom behavior to all "non-user related" pages. Correct me if I am wrong but this is what I gathered sot far.... EDIT on 2021-03-28 ends ------------------------------ What I mean is the following: //this direct subclass of Page is treated differently class DefaultPage extends Page {} //subclass of DefaultPage class ArticlesPage extends DefaultPage {} Ryan in his article suggests that using DefaultPage as a subclasses can be used. However, I found a shortcoming when relying solely on DefaultPage. Let's consider this: //direct subclass class DefaultPage extends Page { public function ___loaded() { /* *___loaded() is called when the page is "prepared" by PW, having all its properties loaded from the database. * Because of this, it can perhaps be used as an init() method, so that * we might further initialize the object before actually using it in our own "client code". */ } } The issue with using loaded() to do our own additional initializations is that in the case of DefaultPage this method gets called for ALL the pages that are instantiated during a normal HTTP request. What I mean is that any code placed into loaded() will be executed for all sorts of pages, not just for our humble DefaultPage object we wanted to instantiate in the first place. Even worse – for some reason unknown to me –, the same DefaultPage object's loaded() method will be executed twice during a single HTTP request of the frontend. All this behavior renders loaded() unable to fulfill the role of an init() method I am looking for. However, I found that the subclasses of DefaultPage work differently, let's say "normally". While DefaultPage takes the place of Page as far as ProcessWire is concerned, any subclass of it does not. This is a very important difference, because the following one behaves differently: //subclass of DefaultPage class ArticlesPage extends DefaultPage { public function ___loaded() { /* * Code placed here always runs just once during a normal HTTP request. */ } } In this case loaded() only gets called by ProcessWire when our own client code triggers the instantiation of the custom page object in any way (for example when the related page is rendered by requesting it in the browser). And in this case no other custom page objects's loaded() method gets called. Moreover, trying to use Tracy (eg. a bd() call) in the loaded() method of DefaultPage is not possible, however, Tracy is readily useable in the loaded() method of a subclass of DefaultPage. To summarize: I found that in the case of a DefaultPage I cannot use loaded() as an "init() method". However, in the case of any further subclasses of DefaultPage, it looks like it is fine to rely on loaded() because it is called only once (after the object has been prepared for us by PW). I'm interested in hearing how others implement a custom initialization method for their custom page objects. Maybe there are better ways to do it than relying on loaded()? Is using loaded() for such a thing is a good idea in the first place? //de
    1 point
×
×
  • Create New...