Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/24/2018 in all areas

  1. And if you want to make it responsive: <div uk-grid> <div class="uk-width-1-6@s"> </div> <div class="uk-width-expand"> </div> <div class="uk-width-1-6@s"> </div> </div> I find most of the time when the grid is not working it's because a div has not been closed somewhere or your parent grid is not setup correctly. It's almost always a markup error somewhere.
    5 points
  2. Creating a support topic for this action now that the new actions-as-modules feature has been added to Admin Actions. Unordered List to Pages An action for the Admin Actions module for ProcessWire CMS/CMF. Creates a structure of new pages from an unordered list entered into a CKEditor field. The nesting of further unordered lists within the list will determine the nesting of the created pages. Created pages get a default template that you select, and you can override this default template per list item by specifying a template name between [[ ]] delimiters. This action can be useful to quickly create a page structure; especially so if you are rebuilding an existing non-ProcessWire site that has a Sitemap page that you can copy and paste from. Usage Install the Unordered List to Pages module. Visit the Admin Actions config screen and enable the "Unordered List to Pages" action for the roles who are allowed to use it. Navigate to Admin Actions > Unordered List to Pages and fill out the config fields: Source Enter/paste an unordered list in the Source field. There is a "cheatsheet" field above that explains the syntax you can use to set some template options for each list item. If you want to override the default template for an item you can specify a template name after the page title between double square brackets. If the template doesn't already exist it will be created. Example: Page title [[staff_members]] You can also specify one or more allowed child templates for a template like so: [[staff_members > manager tech_support]]This would create the page using the staff_members template, and set the allowed child templates of staff_members to manager and tech_support. Alternatively you can specify one or more allowed parent templates for a template like so: [[manager < staff_members]] This would create the page using the manager template, and set the allowed parent templates of manager to staff_members. Parent page Select a parent page that the new pages will be created under. Default template Select the default template to use for the new pages. Screenshots Action config: Result: https://github.com/Toutouwai/AdminActionsUnorderedListToPages https://modules.processwire.com/modules/admin-actions-unordered-list-to-pages/
    4 points
  3. <div uk-grid> <div class="uk-width-1-6"> </div> <div class="uk-width-expand"> </div> <div class="uk-width-1-6"> </div> </div> 1/6 is about as close to 15% you'll get I think. For 25% just use uk-width-1-4.
    4 points
  4. IMHO the uikit docs are somewhat hard to read if you are not familiar with them. I've asked my design-partner a lot of such "dump" questions - everything was there, I just didn't see it as well ? They are more of a reference than docs. Listing all components and all options, but to know how everything plays together you need some experience and practise.
    3 points
  5. Have done it with tags in the end!... simples! ?
    3 points
  6. One more thing - the new version of Admin Actions now automatically "installs" new actions for superusers without needing to first visit the module settings page. Of course you can still go there to adjust the authorized roles and checking "In menu" if you want. Thanks to Robin for pushing me to make this happen ?
    3 points
  7. You can also paste the code in question into Tracy's Console panel. Note the highlighted non-printable character at the end and also if you try to run the code, you'll get a syntax error.
    2 points
  8. Are you logging in as a non-superuser? If that's not it and you have copy/pasted the hook code then it would be worth checking to see if any invisible characters got pasted which will prevent the code from working. I notice that this forum software has gotten quite bad recently at inserting invisible characters into code blocks - I see these characters in the email notifications I get from the forum. Most reliable thing for short blocks of code from the forum is to retype them yourself in your code editor. Another way is to use a tool that shows hidden characters. When I copy/pasted the hook code above into this online tool this is what I got: If that's still not it then I'm out of ideas, but you can try debugging with Tracy Debugger. Assuming you are developing your site locally, you'll need the "Force guest users into DEVELOPMENT mode on localhost" option checked in order to see the Tracy bar when logged in as a non-superuser. Bar dump $id and $page->template->name to check that these are what the hook is looking for in the conditional. I've modified the hook slightly just to make it clearer how the conditional relates to what you will be seeing in the bar dumps: $wire->addHookAfter('Page::listable', function(HookEvent $event) { // Only for non-superusers if($this->user->isSuperuser()) return; // The ID of the page that Page List is listing children of $id = $this->input->get->int('id'); $page = $event->object; // Dump to Tracy bar bd($id, 'parent page id'); bd($page->template->name, 'template name'); // Don't list pages with certain templates under Home (adjust template names as needed) if($id === 1 && ($page->template->name === 'internal_db' || $page->template->name === 'newsletter')) { $event->return = false; }; });
    2 points
  9. Hi Pascal, the question might be redundant, but have you ruled out network latency between the web and database server (e.g. by testing with a local copy)? Are you using InnoDB? If not, that might be a chance for a noticeable improvement. Otherwise, you're at a size where you can't follow a simple optimization guide, and your approach with lazy generation of cache parts is certainly going to be one piece of the puzzle. Our corporate intranet is a little under half of the size of your site given the figures above, but we have a lot less (speak roughly 1000) users. We're using a mix of relatively straight forward markup cache with invalidation on page save and regeneration on access every n minutes/hours, and a few cron jobs that assemble more complex dynamic content and stuff it into memcache, so our approach is not that much different from yours. It might make sense to hook into page save and store as much relevant page data as possible in a single (hidden) field in JSON and only load data that you have to get to through the page's accessors (multi language text fields, page references etc.) to reduce the number of queries, adding the delay to the save operation instead of every load. What @bernhard forgot to mention is that his RockFinder module might be worth a look in that regard.
    2 points
  10. The plan is to have it as an interface to filter from two collections of proverbs, international with 35k items and Finnish with 8k. Filtering would target the proverb text. The db includes thematic categorisation, book references, cross-references for culture/language and various research-related tidbits. There will be other views on the material without the grid (like a digital card per proverb etc.). I like RockGrid very much and the new smart filter is a really nice addition. I will look into paying you after we launch the site.
    2 points
  11. I think that autoload order should be an extra setting instead of choosing between boolean|string|callable|int. Because of that you could choose to use a condition and also give it an order. For example, only execute the module in the backend or when a special user role is active, and then load it with high priority.
    2 points
  12. Just a quick note to say that AdminActions now supports installable custom actions like @Robin S suggested above. He has posted his new Unordered List to Pages action over here: If you have any ideas for custom actions, please take a look at Robin's example, but the key things to note is that you need to include a .module file named like: There are two requirements: The classname must start with "AdminActions" It must have 'requires' => 'ProcessAdminActions' This is the entire contents needed in a file named AdminActionsMySharedAction.module class AdminActionsMySharedAction extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Admin Actions My Shared Action', 'summary' => 'My new action does really cool stuff', 'version' => '0.1.0', 'author' => 'John Doe', 'href' => 'https://github.com/JohnDoe/AdminActionsMySharedAction', 'requires' => 'ProcessAdminActions' ); } } Once the module is installed on a site, AdminActions will detect it and allow users to configure and use it like any other action. A big thanks to Robin for his ideas and significant feedback on getting this implemented!
    2 points
  13. Some time ago I created a site profile for creation of a REST API with ProcessWire. Since I kept struggeling with updating stuff between different projects which use this, I decided to convert it into a module. It is now ready for testing: https://github.com/thomasaull/RestApi Additionally I added a few small features: automatic creation of JWT Secret at module install routes can be flagged as auth: false, which makes them publicly accessible even though JWT Auth is activated in module settings To check things out, download and install the module and check the folder /site/api for examples. If you find any bugs or can think of improvements, please let me know!
    1 point
  14. Hey Ryan, hey friends, we, Mobile Trooper a digital agency based in Germany, use ProcessWire for an Enterprise-grade Intranet publishing portal which is under heavy development for over 3 years now. Over the years not only the user base grew but also the platform in general. We introduced lots and lots of features thanks to ProcessWire's absurd flexibility. We came along many CMS (or CMFs for that matter) that don't even come close to ProcessWire. Closest we came across was Locomotive (Rails-based) and Pimcore (PHP based). So this is not your typical ProcessWire installation in terms of size. Currently we count: 140 Templates (Some have 1 page, some have >6000 pages) 313 Fields ~ 15k Users (For an intranet portal? That's heavy.) ~ 195 431 Pages (At least that's the current AUTOINCREMENT) I think we came to a point where ProcessWire isn't as scalable anymore as it used to be. Our latest research measured over 20 seconds of load time (the time PHP spent scambling the HTML together). That's unacceptable unfortunately. We've implemented common performance strategies like: We're running on fat machines (DB server has 32 gigs RAM, Prod Web server has 32gigs as well. Both are running on quadcores (xeons) hosted by Azure. We have load balancing in place, but still, a single server needs up to 20 sec to respond to a single request averaging at around about 12 sec. In our research we came across pages that sent over 1000 SQL queries with lots of JOINs. This is obviously needed because of PWs architecture (a field a table) but does this slow mySQL down much? For the start page we need to get somewhere around 60-80 pages, each page needs to be queried for ~12 fields to be displayed correctly, is this too much? There are many different fields involved like multiple Page-fields which hold tags, categories etc. We installed Profiler Pro but it does not seem to show us the real bottleneck, it just says that everything is kinda slow and sums up to the grand total we mentioned above. ProCache does not help us because every user is seeing something different, so we can cache some fragments but they usually measure at around 10ms. We can't spend time optimising if we can't expect an affordable benefit. Therefore we opted against ProCache and used our own module which generates these cache fragments lazily. That speeds up the whole page rendering to ~7 sec, this is acceptable compared to 20sec but still ridiculously long. Our page consists of mainly dynamic parts changing every 2-5 minutes. It's different across multiple users based on their location, language and other preferences. We also have about 120 people working on the processwire backend the whole day concurrently. What do you guys think? Here are my questions, hopefully we can collect these in a wiki or something because I'm sure more and more people will hit that break sooner than they hoped they would: - Should we opt for optimising the database? Since >2k per request is a lot even for a mysql server, webserver cpu is basically idling at that time. - Do you think at this point it makes sense to use ProcessWire as a simple REST API? - In your experience, what fieldtypes are expensive? Page? RepeaterMatrix? - Ryan, what do you consider as the primary bottleneck of processwire? - Is the amount of fields too much? Would it be better if we would try to reuse fields as much as possible? - Is there an option to hook onto ProcessWires SQL builder? So we can write custom SQL for some selectors? Thanks and lots of wishes, Pascal from Mobile Trooper
    1 point
  15. I just posted a new version of Tracy that may also help a little with this sort of thing: https://processwire.com/talk/topic/12208-tracy-debugger/?do=findComment&amp;comment=173674 by highlighting invisible characters (as well as the non-printable ones in the above screenshot).
    1 point
  16. New version adds some configurable settings for the ACE code editor used in the Console panel and the File Editor panel: I went with the defaults I like, but adjust to suit your preferences - don't judge my use of spaces over tabs - it's mostly about consistency when pasting into web forums and other places, but if you need another reason: Developers Who Use Spaces Make More Money Than Those Who Use Tabs ? I am also a big fan of 4 character indentation but I do know that some people prefer 2, so take your pick. The one thing that is new is the intro of Show Invisibles being set to true. That results in the following which I find quite useful at times. Note the highlighted (in pink) character at the end. That actually isn't due to the Show Invisibles setting, but I thought I'd include in this screenshot to bring attention to this thread: https://processwire.com/talk/topic/19995-changing-structure-of-pages/?do=findComment&amp;comment=173671 and how the Console panel can be a useful tool in finding non-printable characters that are causing syntax errors in your code.
    1 point
  17. @adrian I'd actually assumed that hidden included unpublished (?). Will sort the changes out in the coming days (public holiday here today, back to work tomorrow).
    1 point
  18. Actually I didn't forget to mention it but I think/thought that it might not be helpful in this case. The performance boost comes from not loading pages into memory and this is especially helpful when you want to show data as a grid. The query itself is a regular PW pages->find() query with lots of joins, so I'm not sure if that would make a difference in his szenario. I far as I understood his problem is the other way round: They do not need to display lots of pages in one grid, they do need to execute lots of different selectors in lots of different places (custom widgets, boxes or whatever you may call them, with custom data). But yeah, you are right. It might be worth a look anyhow ?
    1 point
  19. The docs are definitely tricky to read, and Uikit3 is actually still in RC stage (has been for years). So every time you read them, there are tiny refinements and changes. Yes, they dropped -10 classes and actually didn't have the -6 classes documented until recently, which made it seem that they had been dropped too.
    1 point
  20. It seems that UIKit 3 has dropped uk-width-*-10 classes Something to elaborate https://github.com/uikit/uikit/issues/2250 https://github.com/uikit/uikit/issues/217
    1 point
  21. ok thx just pushed v0.0.12 including aggrid v19.0.0 seems that the scrollbar thing is an issue with aggrid itself and has nothing to do with any of my modules so i'm fine with it. grids can be tricky and i guess they have a good reason why they changed to flex and why the scrollbar is there (i guess it makes other things a lot easier/better). @Beluga I would be interested in how you are using RockGrid and what you think of it so far ? PS: Just added the module to the modules directory.
    1 point
  22. Please take a look about the new autoheight setting https://www.ag-grid.com/javascript-grid-width-and-height/#auto-height Here is an example where you can switch between a fixed height and autoheight: Example With autoheight enabled the vertical scrollbar appears, which might be a small bug in ag grid, but it doesn't bother me.
    1 point
  23. Can confirm everything works. I updated ag-grid soon after I started tinkering with RockGrid.
    1 point
  24. Module has been moved to GitLab. https://gitlab.com/rockettpw/tools/parsedown-extra-plugin
    1 point
  25. @bernhard You should update ag grid to the latest version, as it brings numerous good improvements. See https://www.ag-grid.com/ag-grid-changelog/?fixVersion=18.0.0 and https://www.ag-grid.com/ag-grid-changelog/?fixVersion=19.0.0 I made a quick test with the new version and everything works well in my case. The name of the script has been changed to ag-grid-community.js
    1 point
  26. I've released 1.5.50, now hosted over at GitLab: https://gitlab.com/rockettpw/seo/jumplinks-one This release fixes an issue where calls to sitemap.xml from my sitemap module were being logged as 404s.
    1 point
  27. ProcessWire 3.0.114 is a relatively minor core version update. Most of the ProcessWire stuff I've been working on this week isn't quite ready to commit/release, so will save for later. This version adds a $database->supportsTransaction() method that returns a true or false as to whether or not the current DB engine supports transactions. Or if you give it (as an argument) the name of a table in the database, it'll return a true/false specific to that table. This version also adds importFiles() and replaceFiles() methods to $page->filesManager, which is what manages all the files for a page. These methods aren't likely to be useful in site development, but are useful for a module I'm working on, and maybe useful to other modules, so I went ahead and added them. Finally, probably the most interesting update in this version is that modules can now specify autoload order. This is something that Adrian requested, as TracyDebugger needs to load before other modules, so this update simplifies that. If you develop a module that has a similar need, be sure to see the notes for the autoload getModuleInfo() property in the Module class. That's all there is this week, so I'm not going to do a blog post this week, but stay tuned for more next week! Have a great weekend.
    1 point
  28. 1 point
  29. Hi guys, super sorry for the delay here. @adrian – Will have a look at this now. Would likely want it to be configurable as well. @Nick Belane – I recall noticing this as well. My initial thinking was to ignore it as the plan was to drop the 404 tab in Jumplinks and replace it with a dedicated module that works side-by-side with Jumplinks v2. That said, I just don't have the time. Haven't even managed to get around to finishing the new Jumplinks. So for the time being, I'm going to see what I can do to have the sitemap ignored from the logger.
    1 point
  30. Awesome work Robin - I can see this being my goto approach for quickly getting new site structures up and running!
    1 point
  31. Hi @Martijn Geerts, ran into an issue with ACF issuing notices on L123 of AdminCustomFiles.module due to unguarded access of the "theme" and "process" indexes on the index array. Changed code to: if (isset($this->index['theme'])) { foreach ($this->index['theme'] as $prop) $config->get($prop['type'])->add($prop['url']); } if (isset($this->index['process'])) { foreach ($this->index['process'] as $prop) $config->get($prop['type'])->add($prop['url']); } to fix this.
    1 point
  32. You can Hook into InputfieldFile::processInputFile. There are other places in that Class you could also hook into, but I think processInputFile works best. Throw the code below in ready.php Please note: Starter code: not much validation going on other than checking if the field the file was uploaded to is 'course_file' You will have to implement other logic yourself. For instance, the code copies the file immediately it is uploaded by ProcessWire Ajax. It doesn't check if the page is actually saved. If a page is not saved and the page is reloaded, as you know, files in file fields are deleted from disk. This code does not delete the corresponding file in your custom directory You might want the Hook to only run if you are in admin. You can add that logic I've purposefully left in verbose and debugging code in there (Tracy stuff) to help you ( maybe and others) understand what's going on. I suggest you test using Tracy Debugger for a better grasp of the file upload process. Delete the debugging stuff when you've got this working as you want :-). wire()->addHookAfter("InputfieldFile::processInputFile", function(HookEvent $event) { // @note: here, events are $input, $pagefile, $n @see: the method // get event we are hooking into // get arguments by index {a bit faster, but less-readable} /* $input = $event->arguments[0]; $pagefile = $event->arguments[1]; $n = $event->arguments[2]; */ // get arguments by name #$input = $event->argumentsByName('input'); $pagefile = $event->argumentsByName('pagefile'); #$n = $event->argumentsByName('n'); // $pagefile->field: The Field object that this file is part of. // limit to a specific field {course_file} if($pagefile->field->name != 'course_files') return; # intercept file // Tracy Debugger calls to see what's going on. Also logs Ajax inputs! #bd($input, 'input'); #bd($n, 'input'); // @see: http://processwire.com/api/ref/pagefile/ // pagefile object bd($pagefile, 'pagefile'); // name of the field uploading to {your 'course_file'} bd($pagefile->field->name, 'field pagefile is part of'); // file-sanitized name of the file we've added, e.g. 'checklist_install.pdf' bd($pagefile->basename, 'name of added file'); // full disk path where the file has been uploaded in this page's files folder... //... in /site/assets/files/1234 where 1234 is this page's ID // ... e.g. "F:/www/mysite/site/assets/files/1234/checklist_install.pdf" bd($pagefile->filename, 'full disk path name of added file'); // $pagefile->page: The Page object that this file is part of bd($pagefile->page->id, 'id of the page file added to'); // full disk path to your custom uploads directory $customDirectory = $this->wire('config')->paths->assets . 'custom_directory/'; bd($customDirectory,'custom directory for files'); # copy file // use ProcessWire's $files API // @see: http://processwire.com/api/ref/files/ $files = $this->wire('files'); // copy the file(s) $files->copy($pagefile->filename,$customDirectory . $pagefile->basename); });
    1 point
  33. Just finished the docs for my custom smart filter - if anybody wants to get an idea what is possible just have a look here: https://gitlab.com/baumrock/FieldtypeRockGrid/blob/master/plugins/filters/smart.md
    1 point
  34. You could just create a template called logout.php (and a page called Logout using that template), and link them to that page to logout. /site/templates/logout.php: <?php namespace ProcessWire; $session->logout(); $session->redirect($pages->get("/")->url);
    1 point
  35. What @AndZyk said. Below is one way to do it. Before that though, logic whether something exists should really be done server-side. Yes, you can also do client-side checks the way you are doing it (just for UX) as long as you also validate things server-side. Otherwise, if you only do it client-side, it is easy to change the 'valid until date' of the coupon in the markup and send that to the server which would honour the coupon and you'd incur a loss in your takings :-). I hope you are also checking server-side. OK, here's the code. It makes things cleaner, more readable and is less prone to mistakes since PHP handles the JSON string. <?php // initialise variables $couponsArray = array(); $couponsJSON = ''; // fetch coupons $coupons = $pages->find("template=paddiscount, title!='', pad_percentage!=''"); // we found coupons if($coupons->count) { // loop through coupons and add values to coupons array foreach($coupons as $coupon) { // if coupon valid until, get human readable valid until date, else empty $couponValidUntil = $coupon->pad_valid_until ? date("Y-m-d", $coupon->pad_valid_until) : ''; $couponsArray[$coupon->title] = $couponValidUntil; } // generate JSON string of coupons for JavaScript $couponsJSON = json_encode($couponsArray); } ?> <!-- html here --> <script type="text/javascript">var coupons = <?php echo $couponsJSON ?></script> Then in your JavaScript do your checks, if var coupons is not empty, etc. Hope this helps :-).
    1 point
  36. I've heard WordPress has a plugin for that ?
    1 point
  37. If you want to build a JSON object with PHP, you should have a look at json_encode. That it is easier and cleaner than building it yourself. ? Regards, Andreas
    1 point
  38. The same code will work in a hook to Pages::delete. Adapted to keep it DRY: // Prevent the trashing/deleting of pages referenced by other pages $pages->addHookBefore('trash', null, 'protectReferencedPages'); $pages->addHookBefore('delete', null, 'protectReferencedPages'); function protectReferencedPages(HookEvent $event) { $page = $event->arguments(0); // Find non-system Page Reference fields $pr_fields = wire('fields')->find("type=FieldtypePage, flags=0"); // Implode for selector string $pr_fields_str = $pr_fields->implode('|', 'name'); // Find any referencing pages $referenced_on = wire('pages')->find("$pr_fields_str=$page->id, include=all"); if($referenced_on->count) { // Replace the trash/delete method $event->replace = true; // Link markup for referencing pages $referenced_on_str = $referenced_on->implode(', ', "<a href='{editUrl}'>{name}</a>"); $plural = $referenced_on->count > 1 ? 's' : ''; // Trigger an error message (using $session in case a superuser is trashing/deleting from ProcessPageList) wire('session')->error("You cannot $event->method page $page->name because it is referenced in a Page Reference field on page$plural $referenced_on_str.", Notice::allowMarkup); // Don't allow the trashing/deleting of this page $event->return = false; } }
    1 point
×
×
  • Create New...