Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 06/14/2023 in all areas

  1. Hey! A client wanted me to update their website to make it show dates in the form "1. - 3. Jän. 2023" instead of "1. Jän. 2023 - 3. Jän. 2023" It's a small change but not so easy to solve, especially if you want to make it locale aware etc... So I've created "HumanDates" library which is not a PW module but a standalone PHP class so that everybody can easily use it even outside of the PW universe: https://github.com/baumrock/HumanDates Usage is simple and the library can be used as a strftime replacement: // manual download require_once "/path/to/HumanDates.php"; // using composer // composer require baumrock/humandates require_once "/path/to/composer/autoload.php"; // create HumanDates instance $dates = new HumanDates(); echo $dates->format("2023-01-01"); // 1. Jan 2023 echo $dates->range("2023-01-01", "2023-01-03"); // 1. - 3. Jan 2023 If it is useful to you please let me know by giving it a star on github ? https://github.com/baumrock/HumanDates/stargazers PS: It will be available in RockFrontend in the next release simply by calling $rockfrontend->humandates() ?
    3 points
  2. I've built a commercial module RockForms that can be of huge help here. It uses https://doc.nette.org/en/forms which is the only library on earth that I know where you define all rules from within PHP and get the same exact validation rules also on the client side for live validation. You have tons of options regarding validation and you can even create nested validation rules: https://doc.nette.org/en/forms/validation The drawback of using Nette Forms is that it makes it very hard to customise the created markup of your forms to your needs. That's where RockForms jumps in. Also it integrates everything very well with PW and creates pages from submitted forms, provides hookable methods to do custom stuff at custom events and handles redirects to prevent double form submissions etc.; Basically it handles all the tedious things for you that you'd have to think of upfront or that you have to fix later if you didn't think of them ? A simple form could look like this: // create form with a unique name $form = new RockForm("demo"); // field setup $form ->addText("forename", "Enter your first name") ->setRequired("We need your first name to show it!"); $form ->addText("surname", "Enter your given name"); $form ->addSubmit("submit", "Submit your name"); // render output if ($form->showSuccess($values)) { $name = $values->forename; if($values->surname) $name .= " " . $values->surname; echo "<strong>Thank you for submitting the form, $name!</strong>"; } else { echo $form->render(); } Or for more complex forms you can define everything in OOP style. Extensive docs are in the works and provide live examples that you can play around with: https://www.baumrock.com/modules/rockforms/docs/ Compared to FormBuilder the module does not (yet) have a UI to build forms. That's done in code, but it seems that this is what you want anyhow?! Single Site License will be 49€ - if you are interested write me a PM ?
    2 points
  3. So I've just updated my personal website after some 7 or 8 years. It's a small one pager, but with some quirks that I hope you'll enjoy. Have a look: https://heldercervantes.com/ First, the approach was to somehow reinterpret my CV into a web experience. My last CV, along with my Supertiny agency's website share this space exploration / alien contact theme, so the idea here was to incorporate a journey through space as the user scrolls through the website. In the end you'll find a mini-game, where you can attempt to reach the far depths of space and discover what's out there. Most content is static, but I'm using PW to manage the logos you'll fly by at some point and the projects, the game's highscores and SEO. I intend to improve it a bit in time. Sound is probably the next thing I'll add, and I have some ideas to make the game more interesting. Fun fact: Setting up PW for this one took about 2h.
    1 point
  4. I've just bumped the dev branch version to 3.0.220. Relative to 3.0.219, this version is largely focused on issue resolutions, and there are 11 of them, among 14 commits. See the dev branch commit log for details. This is just a brief update so I don't have more to add other than that I hope you are having a great week, and have a great weekend!
    1 point
  5. You could use a hidden field in the template to store the title of the first repeater item, similar to this: Or you could match the repeater page by sort position and then get the containing page for each matched repeater page. $items = $pages->find("template=repeater_areas, title=$area, page.sort=0, check_access=0"); $results = new PageArray(); foreach($items as $item) { // Get root page that contains the repeater page $result = $item->getForPageRoot(); // Maybe do some checks on $result page here, for example if you only want pages that have a particular template $results->add($result); }
    1 point
  6. Hi @teppo - firstly, just another mention of how important this module is to me - it's always one of the very first installed on every site, so thank you :) Now to some issues / suggestions if I may. 1) We often find lots of revisions listed for a field that simply return "There is no difference between these revisions". I don't really understand why a revision is stored if there were no changes made. It seems like unnecessary DB bloat, but more importantly, it makes it very hard to find the revisions where changes actually are made. Do you think this behaviour could be changed so that no revision is stored? 2) We often see changes to page reference fields (checkboxes in this case, but I expect it probably doesn't matter the inputfield type) where changes are recorded, but in reality, they weren't actually changed - why would they be recorded as being removed and then added again? 3) When you have a page template where the width of fields is a small percentage (25%, 33%, etc), the interface for viewing the revision history is quite awkward, with lots of horizontal and vertical scrolling required. I was wondering whether you think it might be a better experience to load the revisions in a PW panel (pw-panel - https://processwire.com/blog/posts/pw-3.0.15/) Thanks so much for considering and let me know if there is any way I can help with any aspect of this.
    1 point
  7. Looks like you might be saving some unvalidated data in the $currentUser there. I'm not familiar enough with Padloper to know if it handles pre-validating posted data like $input->post->email - but if it doesn't you might be leaving yourself open to stored XSS or an email header injection depending on how that field is used later in the code.
    1 point
  8. Maybe you need to set your field_pass table to ascii_general_ci ? At least this is what it shows for me. Maybe that's messing things up?
    1 point
  9. You don't need composer for RockForms. But if you are building some intranet-like app as @dotnetic mentioned the most efficient way is to stay in the PW backend. To understand the backend better you can read my blog post here: https://processwire.com/talk/topic/17709-how-to-create-custom-admin-pages-aka-processmodules-yes-its-that-simple/ But creating a complex app with lots of calculations is not an easy task - so if composer is out of your league I'm not sure if it's a good idea to take over such a project. Maybe it's better to build on an existing solution as @Jim Bailie mentioned. But that's of course your decision ? Just wanted to mention that you can achieve anything you want with PW and with the PW backend, but it's definitely more complex than using composer. And your comment about PW needing a page title does not sound like you know a lot about hooks or the inner workings of PW. It's of course your decision, just be aware that if you price it with a flat rate then you might end up with a lot more work than you'd expect ?
    1 point
  10. Hi all, I'm having trouble with an import. Some translated text imports correctly, some doesn't. There are no errors or warnings displayed. Background We're running a big import on a file which was originally exported using the built in Export/Import module. Trying this both in the Admin, and by using $importer = new PagesExportImport(); $importer->importJSON($json); Seems like some text imports correctly, some doesn't. Some fields which work are inside MatrixRepeaters, some are just fields on the page. The same field types even work some places but not others. The import runs without error, and the message shown suggests all the fields imported correctly. Debugging I have been trying to identify if anything is failing silently. I've been reading PagesExportImport.php and I think line #978 is the function call where the imported field content is saved: $page->set($field->name, $pageValue) The thing is, when I print the values either side of this function, the field values are correct. I'm not familiar enough with the inner workings of PW to really understand what might be going on. Next steps Where else should I check? Are there any other functions used to save imported field content? Or are there any better ways to go about debugging this? Thanks! Edit - I've attached 2 screenshots. the Messages are with const debug = true; set in ProcessPagesExportImport.module. I believe they show that the import should have worked. The heading screenshot field shows that the translations didn't import correctly. I'm not sure if this is a bug or something I'm missing.
    1 point
  11. That's correct yeah and it did kick me out as expected. Clearing my cookies seems to have worked, thanks!
    1 point
  12. Are we talking about the page with ID 2 in which you changed the name/URL? It might throw you out of the backend but accessing the new name/url should end in the regular ProcessWire backend as usual. Just tried it and all links are working. Maybe clearing all compiled files or deleting local cookies might help in your case.
    1 point
  13. @netcarver & @dotnetic Thank you both for replying that fast. Finally I found the reason: at DSGVO times I tried to avoid cookies as much as possible, so I have the following lines in config.php to let guests without session cookie: $config->sessionAllow = function ($session) { // if there is a session cookie, chances are user is logged in if ($session->hasCookie()) return true; if (!isset($_SERVER['REQUEST_URI'])) return false; // if requested URL is an admin URL, allow session if (!empty($session->config->urls->admin) && strpos($_SERVER['REQUEST_URI'], $session->config->urls->admin) === 0) return true; // otherwise disallow session return false; }; This somehow got stuck - I disabled that part and was able to log in again. After re-enabling the cookie conditions login/out is working as usual again. Thanks for your time - I appreciate it .
    1 point
  14. Thanks Robin! Perfect answer I was hoping to hear. I love Processwire!
    1 point
  15. You can also build the whole application in the admin and have all of ProcessWire´s form validation and possibilities there, like dependend showing and hiding of form fields. I have built several projects for example a job application management system. room management. E-Commerce site with management from order to production inside of the admin. Some of my edit pages even have AJAX calculation fields in them. PDF and chart generation is another thing. I use the edit form of pages to manage different stuff. I also use CustomPageClasses to modify the forms inside of the admin. It depends, if the forms should be customer facing (to the public) or are they just for your client?
    1 point
  16. Obviously this can be done with PW, but it's hard to even know how to re-invent this wheel without spending a day or two interviewing your client and sketching out a stack of wire-frames. Probably not what you want to hear, but I'll just throw this one out there: We've *HIGHLY* customized this gem for 3 mid-sized B2B clients needing pretty much the general functionality you've mentioned. It's based on CodeIgnitor (sp?) and is pretty simple to trick out. https://codecanyon.net/item/perfex-powerful-open-source-crm/14013737
    1 point
  17. Welcome to the PW forums @Tenzing ? You can achieve this by setting the URL segments you want to $input before you render the page. E.g. $input->urlSegment1 = 'foo'; $input->urlSegment2 = 'bar'; echo $thepage->render();
    1 point
  18. Edit: Because of the great response to this topic I wrote a guest blogpost: https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/ One of the hidden treasures of processwire seems to be the creation of custom admin pages. Technically speaking those pages are ProcessModules - but i guess that's the reason why so many people out there seem to be afraid of building them... it sounds so hard! You've never created a module for ProcessWire? You have never created a plugin for any other CMS? You have no clue about OOP with all its classes, methods and properties? No problem! I'll show you how simple you can start: <?php class CustomAdminPage extends Process { public static function getModuleinfo() { return [ 'title' => 'Custom Admin Page Example', 'summary' => 'Minimalistic ProcessModule to show that nobody has to be afraid of building custom admin pages.', 'href' => 'https://processwire.com/talk/topic/17709-how-to-create-custom-admin-pages-aka-processmodules-yes-its-that-simple/', 'author' => 'Bernhard Baumrock, baumrock.com', 'version' => 1, // page that you want created to execute this module 'page' => [ 'name' => 'customadmin', // your page will be online at /youradmin/setup/customadmin/ 'parent' => 'setup', 'title' => 'Custom Admin Page Example' ], ]; } public function ___execute() { return 'This is the most simple Admin-Page you have ever seen :)'; } } Now save this file as CustomAdminPage.module and place it in your /site/modules folder. After a refresh it will show your module in the modules manager of your site where you can install it: After installation you already have your first very own admin page! Congratulations! Was not too hard, was it? It's as simple as that! Now lets add some more custom HTML. And to show you another nice feature we will add this code to a separate method called executeDemo(). And because everything is so simple we will also add some javascript to this page public function ___executeDemo() { $out = ''; $out .= '<h1>H1 has some special css styling in the admin, thats why it seems to have no effect</h1>'; $out .= '<h2>H2 looks different ;)</h2>'; $out .= '<h3>...and so does H3</h3>'; $out .= '<button onclick="myFunction()">Click me</button>'; $out .= '<script>function myFunction() { alert("this is a demo javascript"); }</script>'; return $out; return ''; } Now thanks to ProcessWire-magic your page will already have its own URL: Just append /demo to your url and see what you get: And of course don't forget to click the button Ok, now that code looks a bit hacky, right? Inputfields and especially InputfieldMarkup for the win! We add another method with some advanced code. To use inputfields we need a form that holds all those inputfields and that makes it possible to handle user input lateron. See somas great tutorial about forms here for a quickstart and more details: public function ___executeAdvanced() { $out = '<h2>A more complex Example</h2>'; $form = wire()->modules->get('InputfieldForm'); $field = wire()->modules->get('InputfieldMarkup'); $field->label = 'Markup Test 1'; $field->value = '<h1>h1</h1><h2>h2</h2><h3>h3</h3><h4>h4</h4>'; $form->add($field); $out .= $form->render(); return $out; } Ok, it get's boring Let's do something more fun and add a chart in a second field and change the fields to 50% screen width (I'm sure you know that already from the GUI template editor)! public function ___executeAdvanced() { $out = '<h2>A more complex Example</h2>'; $form = wire()->modules->get('InputfieldForm'); $field = wire()->modules->get('InputfieldMarkup'); $field->label = 'Markup Test 1'; $field->value = '<h1>h1</h1><h2>h2</h2><h3>h3</h3><h4>h4</h4>'; $field->columnWidth = 50; $form->add($field); $field = wire()->modules->get('InputfieldMarkup'); $field->label = 'Chart Sample'; $field->value = '$chart'; //$field->notes = 'Example code taken from here: http://www.chartjs.org/docs/latest/getting-started/usage.html'; $field->columnWidth = 50; $form->add($field); $out .= $form->render(); return $out; } OK, we are almost there... we only need to add the chart library! To keep everything clean we will put the code for the chart in another method. We will make that method PRIVATE to add some security. Our new Method: private function renderChart() { // prepare chart code wire()->config->scripts->add('https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.min.js'); ob_start(); ?> <canvas id="myChart"></canvas> <script> var ctx = document.getElementById("myChart"); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: [ 'rgba(255,99,132,1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero:true } }] } } }); </script> <?php return ob_get_clean(); } Now we just need to call $this->renderChart() in the right place! Here is the complete Module: <?php class CustomAdminPage extends Process { public static function getModuleinfo() { return [ 'title' => 'Custom Admin Page Example', 'summary' => 'Minimalistic ProcessModule to show that nobody has to be afraid of building custom admin pages.', 'href' => 'https://processwire.com/talk/topic/17709-how-to-create-custom-admin-pages-aka-processmodules-yes-its-that-simple/', 'author' => 'Bernhard Baumrock, baumrock.com', 'version' => 1, // page that you want created to execute this module 'page' => [ 'name' => 'customadmin', // your page will be online at /youradmin/setup/customadmin/ 'parent' => 'setup', 'title' => 'Custom Admin Page Example' ], ]; } public function ___execute() { return 'This is the most simple Admin-Page you have ever seen :)'; } public function ___executeDemo() { $out = ''; $out .= '<h1>H1 has some special css styling in the admin, thats why it seems to have no effect</h1>'; $out .= '<h2>H2 looks different ;)</h2>'; $out .= '<h3>...and so does H3</h3>'; $out .= '<button onclick="myFunction()">Click me</button>'; $out .= '<script>function myFunction() { alert("this is a demo javascript"); }</script>'; return $out; return ''; } public function ___executeAdvanced() { $out = '<h2>A more complex Example</h2>'; $form = wire()->modules->get('InputfieldForm'); $field = wire()->modules->get('InputfieldMarkup'); $field->label = 'Markup Test 1'; $field->value = '<h1>h1</h1><h2>h2</h2><h3>h3</h3><h4>h4</h4>'; $field->columnWidth = 50; $form->add($field); $field = wire()->modules->get('InputfieldMarkup'); $field->label = 'Chart Sample'; $field->value = $this->renderChart(); $field->notes = 'Example code taken from here: http://www.chartjs.org/docs/latest/getting-started/usage.html'; $field->columnWidth = 50; $form->add($field); $out .= $form->render(); return $out; } private function renderChart() { // prepare chart code wire()->config->scripts->add('https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.min.js'); ob_start(); ?> <canvas id="myChart"></canvas> <script> var ctx = document.getElementById("myChart"); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: [ 'rgba(255,99,132,1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero:true } }] } } }); </script> <?php return ob_get_clean(); } } I hope you enjoyed reading this and it will open up many new possibilities for you! Updates: permissions: https://processwire.com/talk/topic/17709-how-to-create-custom-admin-pages-aka-processmodules-yes-its-that-simple/?do=findComment&comment=174746 tutorial on file uploads: https://processwire.com/talk/topic/17709-how-to-create-custom-admin-pages-aka-processmodules-yes-its-that-simple/?do=findComment&comment=185261 snippet how to use NavJSON: https://processwire.com/talk/topic/17709-how-to-create-custom-admin-pages-aka-processmodules-yes-its-that-simple/?do=findComment&comment=216412
    1 point
×
×
  • Create New...