Jump to content


Popular Content

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

  1. 6 points
    It depends on how big is big. In one of our bigger projects, we designed the whole system around ProcessWire's page-templates-fields paradigm. It was designed in such a ways that it looked almost like a normalized relational database with PageReference providing the "relationships", but with each page easily editable in the admin. This was working well, until it wasn't. I'm guessing it was because we "normalized" the data too much that we were hit with performance issues when we started making big queries specially with aggregates, and with traversals. Of course this wasn't ProcessWire's fault but our own because we wanted so much to be able to code using mostly PWs API and very minimal raw SQL. Our intermediate fix was to write the queries manually to make the huge queries. But after a while the solution felt dirty, so in the end we refactored our data, pulled them out of ProcessWire's database and moved them to a separate database. We used a half-and-half ORM solution to access the data and wrote custom modules to edit them on the backend as @Macrura suggested. So what I'm trying to say TL;DR is: If you want to use PW to manage your database, it'll be great. It's not how "big" your data is, but how complex the relationships will be. And maybe not even that. It depends on how much you want to rely on the API to get your data. We were doing all well and good until we wanted to get something like $page->parent->child->children()->child on some reports, or something similar which of course resulted in hundreds of JOINS. (Don't do that, seriously, we were stupid. Lazy and stupid ). But if it's something where you're doing huge queries and reports, it will work but it will not be the fastest unless you start writing custom SQL queries. If you're lazy like me, use an ORM if you decide to use a separate database. But this of course will have an overhead in learning curve and in writing the custom modules for the admin. I hope this helps. :/
  2. 5 points
    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.
  3. 4 points
    on the CONTRA side: - i personally wouldn't care much about database bloat - how many records? - speed may not be an issue, depends on how you are using the records, and if you have caching on the front end - vendor lock in - you can easily write a script to export the records into CSV files and import to a new database; the data might change a lot over time, and what if you want to add fields to data types etc. on the 3RD way: you can leave the data in MySQL and access it in ProcessWire but, you can't really edit it that easily unless you start writing custom modules/interfaces and doing SQL queries..
  4. 3 points
    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?
  5. 2 points
    Checkbox Reversed Modifies InputfieldCheckbox so that it shows the reverse of its true value. The checkbox will be unchecked when the field value is 1 and checked when the field value is not 1. Background The core FieldtypeCheckbox does not have a setting that allows a checkbox to be checked by default. One reason for this is that only a checked field saves a value to the database. An unchecked field does not save "0" to the database, but rather does not save any value for the field at all. Therefore there is no way to distinguish between a new field that has not yet been saved (and therefore could potentially get a default checked state) and a field that has deliberately been saved as unchecked. Because of this you sometimes have to use a checkbox in the opposite way than you would like. Suppose your client has requested a checkbox labelled "Bootylicious" that will be checked by default. This isn't possible with FieldtypeCheckbox so instead you have to convince them that a checkbox labelled "Not bootylicious" that is unchecked by default is just as good. This alternative will achieve the same thing, but it's not ideal. A solution This module doesn't change the limitations of the core checkbox field, but it provides a workaround that allows you to show the checkbox with the desired default state and label. So in the example above you would still name the field "not_bootylicious" (otherwise it could get confusing in your template files) but you can label the field "Bootylicious" and the checkbox will appear checked when its true value is actually unchecked, and vice versa. This allows new pages to show the checkbox checked by default. Clear as mud? Usage Install the Checkbox Reversed module. For any Checkbox field where you want the inputfield to show the reverse of its true value, activate the "Reverse the checked state of this inputfield?" option in the field settings. https://github.com/Toutouwai/CheckboxReversed http://modules.processwire.com/modules/checkbox-reversed/
  6. 2 points
    Just a short update this week and we work on the finishing touches for the next master release version of the ProcessWire core: https://processwire.com/blog/posts/processwire-3.0.93-core-updates/
  7. 2 points
    On queries: Execution Times (see Ryan's comments in that thread) findMany() https://processwire.com/api/ref/pages/find-many/
  8. 2 points
    I think this heavily depends on the use cases and the size of the project (e.g. amount of data, people involved). I am currently working on a project where I started to do everything from scratch, but then moved to PW because it saves a lot of time regarding standard functionality (e.g. permissions, login, caching, security in general). I have also worked for several companies building Saas platforms - for these kind of uses cases PW would be not the best choice. The use cases here were much to special, need a lot of DB tweaking, rely on different DB types (e.g. Elastic Search, Postgres, Lucene) and so on. If you want to save time by having standard functionality out of the box: I'd use PW. If you have enough capacity to build this on your own because you expect that you scale that fast that PW is simply the "wrong" framework: I'd think of a pure framework. But as said: It's easy to export data from PW, so this might be a third option: start with PW, scale fast, move to something else
  9. 2 points
    Thanks @Karl_T for the help, I'm almost there now, only some minor glitches are left, eg keeping the searched term after enter. I've decided to destroy/rebuild the select2 dropdown to make sure everything work nicely with asmSelect (had issues otherwise). I've also made the greyed out items hidden, so only the selectable options are visible. Let me know if you have arguments against it. I sorted the field list alphabetically, let me know if you think it's a bad idea.
  10. 2 points
    you may be running into some filecompiler issue, or you have 2 copies of formbuilder somehow in your directory - check to make sure there is only 1 copy of it; you can force the filecompiler to recompile any file by opening it and adding a line at the end, and saving the file; This kind of thing seems to happens a lot when doing upgrades, some modules need to be recompiled for some reason..
  11. 1 point
    Video or Social Post Embed Based on the TextformatterVideoEmbed module developed by Ryan Cramer, we have added the possibility to embed publications of the main social networks Facebook, Twitter and Instagram. ProcessWire Textformatter module that enables translation of YouTube, Vimeo, Instagram, Facebook, Twitter or Issuu URLs to full embed codes, resulting in a viewable video or social post in textarea fields you apply it to. How to install Download or Clone from Github: https://github.com/lexsanchez/VideoOrSocialPostEmbed Copy the VideoOrSocialPostEmbed.module file to your /site/modules/ directory (or place it in /site/modules/VideoOrSocialPostEmbed/). Click check for new modules in ProcessWire Admin Modules screen. Click install for the module labeled: "Video or Social Post Embed". Now you will be on the module config screen. Please make note of the config options and set as you see fit. How to use Edit your body field in Setup > Fields (or whatever field(s) you will be placing videos in). On the details tab, find the Text Formatters field and select "Video or Social Post Embed". Save. Edit a page using the field you edited and paste in YouTube, Vimeo, Facebook, Twitter, Instagram and/or Issuu URLs each on their own paragraph. Example How it might look in your editor (like TinyMCE): How it works This module uses YouTube, Vimeo, Instagram, Facebook, Twitter and Issuu oEmbed services to generate the embed codes populated in your content. After these services are queried the first time, the embed code is cached so that it doesn't need to be pulled again. Configuration You may want to update the max width and max height settings on the module's configuration screen. You should make these consistent with what is supported by your site design. If you change these max width / max height settings you may also want to check the box to clear cache, so that YouTube/Vimeo/Facebook/Twitter/Instagram/Issuu oembed services will generate new embed codes for you. Using with Markdown, Textile or other LML This text formatter is looking for a YouTube, Vimeo, Instagram, Facebook, Twitter or Issuu video URL surrounded by paragraph tags. As a result, if you are using Markdown or Textile (or something else like it) you want that text formatter to run before this one. That ensures that the expected paragraph tags will be present when VideoOrSocialPostEmbed runs. You can control the order that text formatters are run in by drag/drop sorting in the field editor. Copyright 2018 by Ryan Cramer / Updated by Lex Sanchez
  12. 1 point
    Inputfield::renderReady was made hookable as Inputfield::renderReadyHook in PW 3.0.44. So the module could be updated to hook after InputfieldPage::renderReadyHook instead of before InputfieldPage::render - then it will work with repeater fields. That would add a requirement of PW >= 3.0.44, or else the module could check the PW version and hook different methods depending on the version.
  13. 1 point
    Hello Theo: Thanks for your comment; I have made an update to the module that solves this error, please uninstall the module replace with the new version. Regards,
  14. 1 point
    @alxndre Thanks for the insights. So what you are saying is you still used PW, but the really large data-sets are in mySQL, and to gain query speed you used LessQL? Or did you even choose another DB-engine to optimize performance? Another question: Did you compare PW-queries vs. native mySQL queries? Or native mySQL queries vs. LessQL? "how big is big"? Care to give us an idea? 100'000+, millions? btw, there are similar discussions in the forums... @bernhard's CRM case study comes to mind, and a new module in the works.
  15. 1 point
    @theo I've experienced transferring data both to and from ProcessWire with no major issues, and this was before the new import/export features which I haven't tried yet. Exporting data from ProcessWire is straightforward using CSV, or SQL dump. One thing to watch out for (but might not be a problem anymore with the new import/export features) when transferring to ProcessWire is making sure the order of templates are correct, meaning you have to import templates that are needed by other templates through PageReference. But it's all in all relatively painless.
  16. 1 point
    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 } });
  17. 1 point
    As workaround for PageFieldEditLinks inside Repeaters, I've hacked this. Just place the code below in templates/admin.php. (Adjust 'my_template'). if ($page->name=='edit' && $input->get->id) { if ($pages->get($input->get->id)->template->name=='my_template') { $config->scripts->add($config->urls->siteModules . "AdminPageFieldEditLinks/AdminPageFieldEditLinks.js"); $config->styles->add($config->urls->siteModules . "AdminPageFieldEditLinks/AdminPageFieldEditLinks.css"); } } Place the above before: require($config->paths->adminTemplates . 'controller.php');
  18. 1 point
    Hello teppo, fantastic: <?php echo $pages->get('/footer/')->footer1 ?> - this was exactly what i want. It works. Now i have made my footer page hidden in lists an search; it is now not shown in the mainmenu, but shown in my footer on every page. Thanks very much. I think i have to train my english a little bit Tom.
  19. 1 point
    There are also a lot of ways to leak data without having a full server compromise like publicly available sql dumps (put somewhere in the webroot) or permission issues on shared hostings. So encryption does still have a value even if the secret key and the encrypted content are on the same machine.
  20. 1 point
    I know. The problem is that I do not want to add another button to cause unnecessary clutter especially for clients.
  21. 1 point
    One idea would be to clone the core inputfieldPage module and then make the renderReady method hookable. Also we need to ask @ryan if it will be possible to make renderReady hookable like render, or if there is some issue with that; once renderReady is hookable, then this module would be able to use that hook to add the required assets; If you use inputfieldSelectize, you can just make your own edit links on the items, and not need this module.
  22. 1 point
    I also don't quite follow. I'm not sure what pw-panel is so I'll comment on pw-modal. When you open a pw-modal, the contents of that modal are opened in an iframe as has been pointed out to you. This means, you have the parent window (the one that opened the modal) and the iframe. The iframe can open another iframe too, but let's not go there :-). Using JavaScript, the modal and parent windows can talk to each other in our case, because they share an origin. I am assuming, you are opening a page in your Process Module in the modal. E.g., you are in some Inputfield (editing a page), click on some link with pw-modal class whose url is /your-process-module-name/some-page/. The modal will display the contents of /some-page/. Of more importance to you, I am guessing, is detecting ajax requests WHILST in /some-page/. Is that it? Remember, whether opened normally or in a modal window, /some-page/ will load all the assets of your Process Module. So, you should be able to fire Ajax calls from YourModule.js AND you are able to use YourModule.js to communicate with (e.g. ParentPage.js) or update markup on the parent page that opened the modal. Is this what you are after? Sorry, I went on a bit much there, but just trying to get the gist of your question. I may be way off base here, but we'll see .
  23. 1 point
  24. 1 point
    Not sure, but let's go through a few things: 1) Is this a new thing on a version of Tracy that was fine before, or is it a new version of Tracy? 2) Same server / php version as before the issue? 3) What is the OS of the server? 4) Is it an issue on all pages of your site? 5) Does it make any difference to click the PW Info Panel > Clear Session & Cookies? 6) Does restarting apache help? 7) Does the debug bar actually load still? Does it take a long time to load? 8) Are there any huge files in site/assets/logs ? Let me know all that stuff and we'll go from there.
  25. 1 point
    Didn't try the module, but what happens with the data when the module is uninstalled?
  26. 1 point
  27. 1 point
    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:
  28. 1 point
    You can set more advanced labels in a Page Reference field by using a hook. Not sure if there's a better way but here's how I do it. In your Page Reference field settings, choose "Custom format" for the "Label field" setting, and in the "Custom page label format" enter anything you want so long as it is unique to that field, e.g. pwrocks Then in /site/ready.php $wire->addHookAfter('Page::getMarkup', function(HookEvent $event) { $page = $event->object; // Each page that appears in the Page Reference field $key = $event->arguments(0); if($key !== 'pwrocks') return; // the label format specified for the Page Reference field // Now build whatever string you want to show using $page, $page->getForPage(), etc $string = 'Your string here'; $event->return = $string; });
  29. 1 point
    Would be cool to add support where possible. Not sure how you've handled the AsmSelect limit in the as-yet-unreleased AOS update, but maybe part of the JS could be broken off into a piece that is generic to all Page Reference inputfields. It would identify the underlying form element that contains the actual field value, and on change it would check if the limit is reached. If so it would add a class to inputfield container, and trigger some event for the container, e.g. 'limitReached'. If you go that way others can contribute pull requests for the remaining Page Reference inputfield types without reinventing the wheel for the limit check. I'd be happy to contribute here.
  30. 1 point
    Was just wondering why people suddenly started starring my module repositories. Cheers, @adrian
  31. 1 point
    Here's a short (or not so) proof-of-concept implementation that adds symmetric encryption to FieldtypeText and derived types. Supports multi language fields and uses either AES256 from phpseclib or sodium's sodium_crypto_secretbox if available on PHP >= 7.2. Key creation is done in the module's configuration settings. There's also a hookable loadKey method to retrieve the key from somewhere else (needs to return the base64 encoded key).
  32. 1 point
    Try: $mail = new \PHPMailer(); The backslash at the front tells it not to use the ProcessWire namespace
  • Create New...