Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/26/2018 in all areas

  1. Following on from my discoveries mentioned here, I have forked the Indexer Module referred to. Couple of reasons for this - Contrary to my thinking at the time of writing the post linked above, there was a deprecated/removed function in one of the files used. (Absolutely no idea why that wasn't apparent originally - must have been some code that isn't always called.) The module was set up to use executable parsers on the server for preference and only included a PHP parser for PDFs, not .doc, .docx etc word processor files. This is probably not optimal for shared hosting use as including your own executables is rarely, if ever, an option. The fork's repository is at https://github.com/DBPreston/Processwire-site-indexer. I have fixed the error due to use of split(), which was removed from PHP 7.0, and added a .doc parser so that it will now parse word processor files as well as PDFs and updated the module config page to reflect that. In the small amount of testing I have done so far, it seems to be working. Neither parser is perfect and the whole mode of operation of the module (adding a 'keywords' field to every page) may not be perfect for every use case, but it is certainly very useful in some instances. I should be very grateful if anyone has the time to give it some further testing, forking, pull requests etc.
    9 points
  2. Solved! if($foo instanceof Page) $foo = $foo->and(); Nice and tidy.
    8 points
  3. More updates! Here is what was added since my last post: FieldtypeDatetime now supports format argument. Which allows you to pass PHP date format string and retrieve your datetime values formatted the way you want. Besides FieldtypeDatetime fields, the built-in fields created and modified are also support new format argument. FieldtypeOptions is now supported. first and last fields on PageArray types are now supported. As per @eelkenet's request. See above post for details on those. Finally, now there is a way to add support for any fieldtype you want via third-party module. What you need to do is create a module with the name exactly as the fieldtype you want to add support for with "GraphQL" prefix. So for FieldtypeMapMarker it would be GraphQLFieldtypeMapMarker. Then you need to add three required methods and install it. This will automatically add GraphQL support for your desired fieldtype and it will be available in your GraphQL api. Checkout the documentation and an example module for reference.
    6 points
  4. I had some tough night hours to figure out things but finally it seems to works as I expected. I kept the hidden items visible because it causes less frustration. Ajax loaded fields are supported though it's still a setTimeout hack, but better than nothing imho. Keeping searched term is still not solved, not sure if I can do that but I think it's still an improvement to the original asmSelect.
    5 points
  5. $pages->find($selector, ['load_options' => ['joinFields' => ['title']]]); This should allow you to join fields on demand.
    4 points
  6. This is where I first read about it: https://swizec.com/blog/how-to-properly-wait-for-dom-elements-to-show-up-in-modern-browsers/swizec/6663
    4 points
  7. current state: https://github.com/processwire/processwire/commit/8fe1eb13f4cbc85c6d5dad093fc559c438c92667#commitcomment-27795259 - sadly I will not have more time this week.
    3 points
  8. Hi Louis: In the information array of your module you can add 'permission' => 'permission-name', add this permission to the role you need edit or use this module.
    3 points
  9. It can be used out of the box when jQuery is used for AJAX, more: https://processwire.com/talk/topic/15809-sessions-db-http404/?do=findComment&comment=141119 Hidden pages are still accessible via their URL so you can use it if your page template file handling the AJAX request is not used for displaying anything else. Unpublished is not accessible (except for logged in superusers) so you need to publish it. A page can be dedicated solely to be an AJAX call processor if you wish to, just check for the sign of an AJAX call, echo your output and use return $this->halt(); to stop the process. Since such a setup is a normal page request it behaves like one, so that is why "ifs" are needed. Here is Ryan's post about the basics: https://processwire.com/talk/topic/225-how-to-work-with-ajax-driven-content-in-processwire/ If you redirect to 404 if it is not an AJAX call, it should be enough to make sure such a page is practically nonexistent for the outside world.
    3 points
  10. Autojoined (autoload) fields are loaded into memory every time a page is called, in contrast with non autojoined fields which are fetched only when they are used. // if title is autojoined (by default) $something = $pages->get(123); // get a page from db echo $something->title; // no extra db hit because it was already fetched when the page was loaded echo $something->else; // pw will query the db to get the field
    3 points
  11. The Fotomediale is a annual festival of photography for children's and youth photography in Freiburg, Germany. This small website provides information about the festival and its workshops. Because of the topic, this site is very picture heavy. Almost every page contains it own set of images displayed in the background. The images cycle through automatically, but you can also use the buttons on the edges (or if you want arrow keys on your keyboard ). If you want to see the images, you can collapse both the navigation and content area. The transitions between pages were made with Ajax and pushState, but you can also access them directly via their URL. To handle the large image backgrounds, all of the images are lazy loaded using lazysizes. The registration form was created using the API. www.fotomediale.de Modules used: ProCache Markup Sitemap XML Email Obfuscation (EMO) Tracy Debugger Regards, Andreas
    3 points
  12. Without trying to invalidate the endresult – mysql + joins will probably be faster – your example code is comparing apples to oranges. A $page->findMany does do quite a few things more than just a db query for data even if it's just constructing the Page objects and putting stuff in different caches. Also I'm not sure your title field is set to autojoin? If not that means you're comparing a single DB query to 4068 DB queries (1 for the items and one for each title). In cases where you're iterating a lot of pages you'll need to keep a look at the query count and not fall into n+1 problems.
    3 points
  13. Hi everyone, I know we'd all like to see ProcessWire grow in popularity (maybe not hugely, but just enough that more people know about it which can help to convince clients to go with it). It strikes me as strange that the ProcessWire Github repo still has less than 300 stars - I'd like to see us well over a thousand which should be an easy task for the forum members to achieve. I see so many other projects with lots of stars but for some reason it doesn't seem like it is something we tend to do around here, despite being a very active, friendly, and supportive environment. I also think that starring your favorite modules doesn't hurt either - I think that will also help to increase the visibility from PW and also help out module authors a little as well. If you can show your Github project has a decent number of stars it shows that you are building things that people want which can help you land a job and helps you to convince the client that you and ProcessWire are a good mix. Anyway, if you have a minute to do some starring of PW and your favorite modules, hopefully it will benefit us all a little. Thanks!
    2 points
  14. http://modules.processwire.com/modules/admin-page-field-edit-links/
    2 points
  15. Thank you @horst for everything you have done for images in PW - you deserve way more recognition than you are getting!
    2 points
  16. module admin page field edit links
    2 points
  17. Check out the PW cheatsheet - it's on there. Thanks for noting the error if no matches are returned. Not sure if @bernhard fixed that further along in that thread - I know he tweaked things quite a bit.
    2 points
  18. Thanks @adrian, requestAnimationFrame seems to work beautifully at first, even in IE11.
    2 points
  19. OK, let's try debug this. The code works for me, so maybe I didn't understand your setup. That's what I have in my code. There are two possible pages that can be referenced. (1). mannequin-modele with ID 1024 OR (2) autre-artiste with ID 1025. Of course, these are the IDs I used in my example and need to be edited as per your needs. I'll try to post an animated GIF/video of my test setup to see if it matches yours. This bit I don't get. First, I thought the child pages are edited manually in the backend. A choice is made, the page is published which triggers the Hook to move them to their new parent and change their template. Is that not the case? What form is this? What sort of code does it contain? Is it being sent from the frontend? Secondly, are you saying you are posting the form to ready.php? How are you doing that? I am not sure ProcessWire will allow you to do that. Incidentally, are we talking about the same ready.php found (or created) under /site/ready.php ? Without question, yes . I'm happy to have a look if the site is online if I could get a temporary access.
    2 points
  20. Thanks, I'll try that way. This solution is much more useful to know than the whole feature in question
    2 points
  21. @theo - here's another approach that you might like to add to your arsenal. Note that this was just an experiment on my part and there will be an upper limit on using the results of findIDs in an SQL query like this, but if you follow the rest of the discussion on that thread you'll get an idea of the pros and cons. https://processwire.com/talk/topic/15524-preview-rockdatatables/?do=findComment&comment=158104
    2 points
  22. Update re previous post Following on from a bit more testing, I have forked the Indexer module mentioned above and started a new thread...
    2 points
  23. Sounds to me like there's a bit of a misunderstanding here. First of all, fields are connected to templates (home, basic-page, etc.) and field values are applicable to pages using that template, so technically there's no such thing as a field with the same global value everywhere. You can solve this in a different way, though. Taking a step back, what you originally asked for was ... The easiest way to achieve this would be adding those fields to an existing template – such as "home" – and filling in the values for a page using that template – in this case your home page. Then you can do something along these lines in your _foot.php file: <?php echo $pages->get(1)->footer1; ?> In other words you can fetch a specific page ("1" in this case means the page with ID 1, i.e. your home page) and then output the value of the field ("footer1") from that page. From what you've written above, it sounds like you might've created a new template called "footer", added fields to it, and then perhaps created a new page using this template too. Sound familiar? If so, you can also use that page as well (instead of, say, your home page) to store your footer values: in your _foot.php you can get that page and output the value from it with <?php echo $pages->get('/footer/')->footer1 ?>. Does this make sense to you?
    2 points
  24. I have launched my martial arts website at https://merpatiputih.com.au/ As a martial arts instructor, my problem was how to track student attendance, payment, course modules, and exercise /health progress report etc. and from my part, I need to publish the class event, schedules, location, and exercise modules for that event. For public viewers, I just simply use blog profile module and UIkit. It's very easy and quick to set-up. The purpose of this site is for a logged-in member where from their mobile they can check-in to the available class a day before, and update their health record after the class. For user front-end, I'm using <region> and delay output. I found this method is really efficient to manage the HTML output, clean and simple. Less headache with templates structure. Below are the functions and modules of this web apps: For Course sessions I'm using page reference, Profields Repeater Matrix and Schedule Pages Module. Profields Table to generate the student records and reports. Calendar for recurring class sessions through the year based on student ranks, selected by user Roles. I only need a simple calendar function (a quick search from the Internet) that able to receive a month and year input. Then, by using region, events field, Profields Repeater Matrix and URL segment it was reduced my time to code complicated function for the event schedule. The only thing here that I have to manage in date calculation is the time format, in Australia we use d-m-y. The tricky thing to get Next month (month + 1), I have to modify it to the first week to get a proper next month. To avoid inquiry about forgot password or username, student logs in via Facebook Login module. Here is the screenshot of student report:
    2 points
  25. Do you need to actually update the sub-domains in the sense that you want to save to their databases OR Do you need them to reflect some changes made to the central site? (i.e. changes made and saved in central site database) If #2, the you can pull the changes made in the central website and display them in the sub-domains using ProcessWire's multi-instance feature Actually, if #1, you can also use multi-instance but that will need a bit more work since you will have to be saving to sub-domains as well. What sort of updates will these be? Text? What about the fields, complex (like Repeaters) or Text inputs? You will also need to decide on what triggers the 'fetching' or 'pushing' of new data from/to the sub-domains. Cron? Web views? You could also use REST API for this. In a hurry, hope above make sense.
    2 points
  26. https://www.baumrock.com/portfolio/individuelles-crm-und-controlling-tool/ I'm happy to share my biggest and most interesting ProcessWire project so far with you It's a 100% custom office-management solution that helps my client to keep track of all their contacts, projects and finance/controlling stuff. Conception was done back in 2016 and the software is productive since begin of this year. My client is very happy with the result and so am I. Some technical insights: Everything is done inside the PW Admin. I'm using the Reno Theme with some custom colors. In the beginning I was not sure if I should stay with the pw admin or build my own admin-framework but now I'm VERY happy that I went with PW Almost all of my custom Process Pages use my RockDatatables module - there are still some limitations but without it, this project would not have been possible For the charts I used Google Charts and chartjs - both play well together with the datatables and make it possible to display filtered data instantly: also my handsontable module was created for this project to have a nice and quick option for matrix data inputs: Lister and ListerPro were no options as i needed much more flexibility regarding data presentation (like colorization, filtering and building sums of selected rows): invoices are highly customisable as well and easy to create. PDFs are created by php and mPDF by the way: all data is dummy data populated via my Module RockDummyData have a nice weekend everybody
    1 point
  27. I think I have finally fixed this! woot woot. Thanks @adrian for all your help. I have attached a new .js file. Let me know if that works for you. rrule-gui.js
    1 point
  28. It's all in the documentation here . Please also read the last couple of post above yours. Since your site uses various languages, you need to pass render() either the ID of your menu, its Page object or an array of menu items. As per the post above yours, this limitation will be resolved in an upcoming update.
    1 point
  29. Tracy Console? ... <google> ... Tracy Debugger ... Wow! What a wonderful tool! I should have discoverd that earlier. I think it would deserve a place on https://processwire.com/docs/tutorials/ Anyway, my problem persists even when trying the command above. My PW version is 3.0.61
    1 point
  30. What? No Opera Mini support?
    1 point
  31. https://caniuse.com/#search=requestAnimationFrame
    1 point
  32. Wonderful! I asked myself if I should tackle this when I wrote that thread, then forgot about it, and now this. I'll definitely test it out this week, because the current project (or rather, the client) uses so many PDFs, it drives me crazy.
    1 point
  33. Never mind, I think I understand. foreach ($pages->findArray("template=families, sort=title, limit=5000", array('title'), 'array') as $p) { foreach ($pages->findArray("parent=" . $p['id'] . ",sort=title, limit=5000", array('title'), 'array') as $m) { foreach ($pages->findArray("parent=" . $m['id'] . ",sort=title, limit=5000", array('title'), 'array') as $s) { echo ($p['title'] . ' ' . $m['title'] . ' ' . $s['title'] . '<br>'); $count++; } } } And it is a lot faster. Thank you!
    1 point
  34. That should make your work a bit easier then. Note that currently, multi-instance requires that your PW installations are local (i.e. on the same server) and accessible on the file system. https://processwire.com/blog/posts/multi-instance-pw3/ The difficulty in your case is editing the template files responsible for pulling data from the central site. Say the data from the central site will be pulled by home.php template files in your sub-domain sites, you will have 100+ home.php files to edit (hopefully once). On the flip side, it means you have per/site control about the data from the central site you want a sub-domain site to pull in.
    1 point
  35. That's why approach I linked is so easy to work with - let PW take care of getting all the matched IDs and then getting the fields you need from that match via SQL. At least I think it helps your situation, although honestly I didn't read through this thread very thoroughly, so maybe I am not getting all the issues.
    1 point
  36. You might also find this interesting: https://jsperf.com/requestanimationframe-vs-setinterval-loop/7
    1 point
  37. Thanks szabesz. I had seen some info about that and have made a "loadmore" template and set up some kind of page. But how should I configure that page? I have it hidden etc., but you still have to publish it, right? Will it behave exactly the same as a plain php inc template part? Or do I have to do other things to prevent it from being parsed and filtered etc.? What is the mysterious $config->ajax; ?
    1 point
  38. @modifiedcontent Hi, a few starting points: https://processwire.com/talk/topic/17320-call-to-undefined-function-wire-with-ajax/?do=findComment&comment=152180 https://processwire.com/talk/topic/17217-getting-content-in-user-language-in-templates-outside-of-template-folder/?do=findComment&comment=151215 Hope this helps.
    1 point
  39. @Robin S Thank you once again for your explanations and all help. You were right, the issue was that all dynamically added options were not inside valid options of Input field. Got it working by putting all possible options before input processing. $wire->addHookBefore('InputfieldSelect::processInput', function($event) { $field = $event->object; if ($field->name === 'product_uses') { $items = $this->pages->find('template=repeater_product_uses_list')->explode('title', ['key' => 'id']); $field->addOptions($items); } });
    1 point
  40. I don't understand them either. Was just working based of the sample's. I googled and it does not seem to matter if you use one block or more. I did quick and dirty fix... looking like this. Note I always have atleast 2 schemes and therefor kinda hardcoded the brackets. There is also a ',' between 2 schemes. <?php $jsonld = $modules->get('MarkupJsonLDSchema'); ?> <script type="application/ld+json">[ <?php switch ($page->template) { case 'product': $options = array( 'logo' => $pages->get(1)->logo->size(200, 200), 'image' => $page->images->first()->size(200, 200) ); echo $jsonld->render('Product', $options) . ","; echo $jsonld->render('BreadcrumbList'); break; case 'categorieen': $options_c = array( 'logo' => $pages->get(1)->logo->size(200, 200), 'description' => $page->summary, 'image' => $pages->get(1092)->images->first()->size(200, 200) ); echo $jsonld->render('Product', $options_c) . ","; echo $jsonld->render('BreadcrumbList'); break; default: $options = array( 'logo' => $pages->get(1)->logo->size(200, 200), 'image' => $page->images->first()->size(200, 200) ); echo $jsonld->render('WebPage', $options) . ","; echo $jsonld->render('LocalBusiness') . ","; echo $jsonld->render('BreadcrumbList'); break; } ?> ]</script>
    1 point
  41. Yes it does, thanks. Silly me, I had the Debug panel open from the standard (non-AJAX) bar and for some reason was imagining it might update in real time. I didn't think to check the AJAX bar.
    1 point
  42. It should already do that. Here's an example showing a selector query in the Console Panel and the selector and resulting query in the Selector Queries section of the Debug panel that is on the AJAX bar. Does this work for you?
    1 point
  43. We still used ProcessWire in areas where it makes sense like users management, presentation related stuff, routing, web API, etc. We moved all business objects to a separate database (MariaDB, InnoDB engine) and used LessQL to simplify data access. We specifically picked LessQL because working with it still somehow feels like working with the PW API. $people = $lessQL->person()->select("id, firstname, lastname")->where("firstname LIKE ?", "%alex%")->orderBy("firstname")->limit(10); About this: $page->parent->child->children()->child Well this is an exaggeration, but we really did have something similar. We worked with a C# ORM before this where it was perfectly okay to do: // pseudocode totalForThisOrderId = person.orders(id).items().sum(price) And as I've said, this was not a problem with ProcessWire itself but with the way we designed our data structure in the PageTree where we had: Transactions \_ Transaction #1 \_ Line Item #1 \_ Line Item #2 \_ Transaction #n \_ etc... So now to get the sum of the line items from the transaction where a line item comes from we'd write: $sumTransactions = $lineItem->parent->children()->sum('price'); It's far from ideal, but it was the quickest way at the time to code based on our previous practice. We're currently at around 50 million records, I think. But like I said, ProcessWire gracefully scales with this. It only starts slowing down when you try to aggregate or count something huge. We were doing reports on hundred thousand records at a time. It still worked, but it was far from fast -- which was mostly our fault. Using LessQL with ProcessWire allowed us to transition without starting over from scratch, and still have the all the benefits of ProcessWire which made us decide to use it in the first place.
    1 point
  44. Just created a new post. This takes into account your updated OP. Since you are in a multi-lingual setup, I've decided to use IDs rather than names. Less user-friendly, but with inline comments, you should be fine. In /site/ready.php $pages->addHookAfter('save', function($event) { // get the page object saved $page = $event->argumentsByName('page'); // only on pages with the temporary template or their parent has the temporary template if($page->template !='directory_page_temporary' || $page->parent->template != 'directory_listing_temporary') { $this->message('page has wrong template'); return; } // if page still unpublished return if($page->is(Page::statusUnpublished)) { $this->message('page still unpublished'); return; } // no choix made yet, return. qui_1 is a page field of single type if (!$page->qui_1){ $this->error('You need to make a choix!');// OR show message instead //$this->message('You need to make a choix!'); return; } // good to go; assign new parent and template # determine new parent and new template $p = ''; $t = ''; // choix: mannequin-modele (this choix page has ID 1024; easier to check by ID in multi-lingual site) if($page->qui_1->id == 1024) { $p = 1021;// new parent is mannequins-modeles and has ID 1021 $t = 'directory_page_mm'; } // choix: autre-artiste (this choix page has ID 1025; easier to check by ID in multi-lingual site) elseif($page->qui_1->id == 1025) { $p = 1022;// new parent is autres-artistes and has ID 1022 $t = 'directory_page_autre_artiste'; } # save if($p && $t) { $page->parent = $p; $page->template = $t; $page->save(); $this->message('page template and parent changed'); } else { // some error } });
    1 point
  45. Hey @eelkenet! That seems reasonable to me. I was planning to add those fields. Didn't have time till now. I'll let you know as soon as I implement them. You won't be able to add those fields via getQuery hook btw. The getQuery hook is there for very trivial custom fields to be honest. Like your api version number, or your contact data or anything you want to send via GraphQL api without creating templates, fields and pages for it.
    1 point
  46. Yes is normal. _init.php the page is already rendering and the APi vars are extracted.
    1 point
  47. If the name is the same on alternative languages, PW doesn't store it cause it's redundant data. The first code is wrong, as there's only "name" in a find selector not a "name[LANGID]". You don't need to handle the language as it's handled by the user language already. The second code needs a second param to be "true" to get the default name if the localized is empty. $page->localName($lang, true). /** * Add a Page::localName function with optional $language as argument * * event param Language|string|int|bool Optional language, or boolean true for behavior of 2nd argument. * event param bool Substitute default language page name when page name is not defined for requested language. * event return string Localized language name or blank if not set * * @param HookEvent $event * */
    1 point
  48. Hey @bernhard - I just quickly hacked together a new $pages->findArray() method that you can use like this: $pages->findArray("parent=12593", array('title', 'integer'), 'object'); It takes 3 arguments: selector array of fields to return return an array or object It needs to be cleaned up (eg properly bind values etc), but as you can see in the screenshot below that it returns an array of the requested fields for 5000 pages in 66ms. I wonder whether there is justification for something like this in the core? It seems like a pretty efficient way to get just the fields you're interested in without the overhead of page objects. You can obviously then do: Object foreach($pages->findArray("parent=12593", array('title', 'integer'), 'object') as $p) { d($p->title.':'.$p->integer); } OR Array foreach($pages->findArray("parent=12593", array('title', 'integer'), 'array') as $p) { d($p['title'].':'.$p['integer']); } This certainly isn't specific to your module - I am definitely going to be making use of this in the future for my sites when I need data for tables / charts, etc. Here is the hook code: BTW - the "title" field in the results below is correct to be a number - these were 5000 API generated pages with numeric titles.
    1 point
  49. PageTable is not supported yet. To be honest I am very busy right now and don't have much time to update this module. So I can't say when additional features will be added. Until then, you'll have to figure out your own way. Sorry
    1 point
×
×
  • Create New...