Jump to content


Popular Content

Showing content with the highest reputation on 09/19/2019 in all areas

  1. 4 points
    There is another option to use Processwire explode. As example: $selectors = "parent=$parent,template=page_car,dealer={$dealer_id}"; $cars = $pages->findMany($selectors); $manufacturers = $cars->explode("manufacturer"); Also later you can do and other things, $manufacturers->sort("title") etc... And there are and other nice WireArray methods like implode, filter, and many others... Regards.
  2. 3 points
    Hello for all, and for my friend @Leftfield Sorry, but I need to say that I agree with @wbmnfktr in your previous post ("... why do you want/need such a weird URL?")? Here is one solution (as option) with default Processwire (no hooks, custom modules or core hack): 1) template: product, fields: title, details (page table with auto name date format) 2) child template: details, fields: image, color, size, price # With that you will get paths (URL's): # Backend administration: # Page tree: There is always option to develope custom module with different UI (and Ajax processing) where user in one "container" write title (parent page), and in another product details (child page). For users all that can looks just like a single UI form that they don't know that are 2 pages. Right now, I see this as one option (or something in this direction) how to get that what you want, but also in all that respect PW core. But need to think is this all worth it (complexity in backend, and later in frontend..).
  3. 3 points
    *pops head up* I seem to be getting a few more ecommerce enquiries nowadays so happy to test when you're at that stage.
  4. 2 points
    Hi guys, today I want to share a little preview of my newly developed ModulesManager 2 module which is currently in beta. ModulesManager 2 provides an easy to use interface to download, update, install, uninstall and configure modules. It is meant to provide an optimized alternative to the ProcessModule dashboard. Maybe @ryan agrees to merge it to the core at some point when it is finished and polished. Features: Live-Search (aka find as you type) for categories Live-Search (aka find as you type) for module names Modern UIKit design Quick uninstall of a module Caches the module list from modules.processwire.com directory locally. There's a refresh button to get actual data. Preview video (with voiceover) Why a new module manager? Some people including myself think that the actual module installation in ProcessWire could be improved in many places. Make it easy for everybody! Lower the barrier for new users, and make it easier for existing users to find an install modules. That is one thing, that many other frameworks/CMS's have by default. Like ModX, WordPress or PrestaShop. What are the disadvantages of the actual core module interface? Installation of a module is not very user-friendly: You have to be aware where to get new modules, search for a module, copy or remember the module name or URL, go back to your ProcessWire installation, paste the module name , or URL, click on "get module info" and finally install the module It only displays installed modules, not the ones that are available in the modules directory, so it makes discovering modules hard. Uninstalling a module requires you to go to the module detail page, click a checkbox and then submit the change. After that you have to go back to the module overview page. It displays only limited information about the module History Back in 2012 Soma came up with ModuleManager, a module which displays modules as a table and provides functionality to download, update, install and configure modules (same as this module does). Sadly this module isn't maintained anymore (but it is still working) Then in 2019 Adrian came up with the idea of autocompleting the module name and Robin S developed the AutocompleteModuleClassName module which does this. This approachis a nice addition for devs who know which module they are looking for. But for all others we need a browsable experience, which provides more info than just the name. This was the perfect time for me to chime in, as I thought that module management is very cumbersome at its current state. A quick proof of concept / prototype was quickly developed. But then development slowed down, as I had to get more experience with vue.js first. Even as I was more experienced I stumbled into some problems that were to advanced for me to tackle. So I hired someone to help (yes, I even paid money for developing this module) TODO Install multiple modules at once like it is done in [ProcessModuleToolkit](https://github.com/adrianbj/ProcessModuleToolkit) add filter by installed/not installed / updateable / recommended switch between card and table layout (table for quicker overview and managing, cards for better exploring, the choice is yours) Allow "search for module" to search in the description also, so a module can be found by its purpose and not only by its name Integrate the Readme or changelog of a module as it is done in [ModuleReleaseNotes](https://processwire.com/talk/topic/17767-module-release-notes/) This would have the following benefits: Make discovery of a module's changes prior to an upgrade a trivial task. Make breaking changes very obvious. Make reading of a module's support documentation post-install a trivial task. Make module authors start to think about how they can improve the change discovery process for their modules. Make sure the display of information from the module support files/commit messages doesn't introduce a vulnerability. I need your feedback This module is in development right now, and I am happy to discuss with you and get some feedback. I will publish it on github as soon as I have the time, so you can download it and analyze the code, and even provide pull requests. What do you like? What is missing? What could make the process even easier?
  5. 2 points
    @CrazyEnimal, please insert your code inside a code block in forum posts. You can use SQL in ProcessWire when it suits you. That's what the $database API variable is for. Here is one way you could get a listing of manufacturers with the number of occurrences within a selection of cars. // Get the IDs of the cars $car_ids = $pages->findIDs("parent=$parent, template=page_car, dealer=$dealer_id"); // Get table for manufacturer Page Reference field $table = $fields->get('manufacturer')->getTable(); // Get manufacturers that are selected in the car pages $query = $database->query("SELECT data FROM $table WHERE pages_id IN (" . implode(',', $car_ids) . ")"); $manufacturer_ids = $query->fetchAll(\PDO::FETCH_COLUMN); // Count how many times each manufacturer occurs in the results $manufacturer_occurrences = array_count_values($manufacturer_ids); // Sort the results in order of occurrences, highest to lowest arsort($manufacturer_occurrences); // Get the manufacturer pages $manufacturers = $pages->getById(array_keys($manufacturer_occurrences)); // Output a list of manufacturer titles and the number of occurrences foreach($manufacturers as $manufacturer) { echo "<p>{$manufacturer->title} ({$manufacturer_occurrences[$manufacturers->id]})</p>"; }
  6. 2 points
  7. 2 points
    Assuming the categories are assigned to locations by a Page Reference field named "categories": $locations = $pages->find("template=location"); foreach($locations as $location) { foreach($location->categories as $category) { echo "<marker title='$location->title' category='$category->title'/>"; } }
  8. 1 point
    Ok, I think I have narrowed it down - if you don't have "overwrite" checked and you use $file->mtime it doesn't know how to name the file at the correct point it needs to. It's also necessary to have "Rename on Save" checked to have this problem. Let me see if I can fix.
  9. 1 point
    @Robin S Thanks, that's perfect. I can't believe it was that simple; I was definitely over-thinking it, trying things like append and add. Many thanks. - P
  10. 1 point
    New Release 0.6.3 – Codename »hehehe« The last release with a "fix" to the login screen actually broke stuff more than fixing it (thanks @johndoe for reporting this). So this is a fix for the fix… Sorry about that. And some improvements to the login screen on mobile devices. Support Forum ProcessWire Modules Repository Gitlab & Issues Added Fullscreen login screen on mobile 📲 Improved notifications on login screen Fixed Fixed Login screen design 🤯
  11. 1 point
    I really feel this is a good thing that it's still only working that way. I get that there's no great way to discover modules, but I also feel that "discovering modules" is a totally different tasks to "managing modules on the system", which is what the current modules section in processwire is about. The ability to install just by name from the modules directory is imho a nice to have convenience and not an unfinished start of integrating the modules directory as the source for modules. The modules directory is just one source for modules, possibly the biggest at least for open sourced modules, but not the only one. This is not to say though that a module filling the gap of "discovering modules" isn't useful and what you created seems like a very nice way to browse the directory and move a module from being listed there to actually being downloaded/installed. I'd personally wouldn't like to see the current module section replaced though. This hint's at the reasons for the above. Browsing the modules directory is great with a cards view. Maintaining installed modules is a totally different task. It needs modules to be quickly scanable - table layouts are way better at that -, it needs to highlight different data - a version is more important than a lengthy description of what the module does, or how many hearts it got - and I'll also hardly switch rapidly between browsing and maintenance so it doesn't need to be co-located in the interface. That part I'd like to see in the core (a bit depending on how it's implemented though). This is an improvement to the "maintaining modules" part of having installed modules, but rather nice to have when browsing modules. To summarise: I really like the problems you're tackling with your module, but personally I'd like to see the efforts split up. The part about "discovery" is great, but certainly not essential to processwire and should in my opinion be either not in the core or at least not installed by default. The part about better maintenance of modules and maybe touching up the UX of the current modules section by lessening the clicks to handle certain usecases is something anyone would benefit from.
  12. 1 point
    In PW you cannot have multiple sibling pages with exactly the same name. That's why the pages are automatically renamed - otherwise you would see an error message.
  13. 1 point
    Maybe it's a matter of rethinking this in light of what the real objective is. I'm guessing that when the notify_user checkbox is checked and the page is saved, something happens - some sort of action that notifies a user. You're saying that you want to force the notify_user checkbox to be in a checked state if the categories field is changed, presumably to force the action to happen. So why not just do the action if the categories field has changed? $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); // If the notify_user checkbox is checked or the categories field value has changed... if($page->notify_user || $page->isChanged('categories')) { // Do the notify user action... } });
  14. 1 point
    So the $pages->find finds the page in the 3rd url segment and displays the content of that page? I guess I don't understand why that is better than having a template file for the document template - I am sure I am missing something, but maybe if you could better explain what you are actually trying to accomplish by doing it this way we might be able to offer some other/better alternatives.
  15. 1 point
    AdminBar 2.4.0 is out and adds support for the "data-adminbar-adjust" attribute. The idea here is to automatically modify (or adjust) certain CSS properties whenever the height of the Admin Bar is recalculated. Note: AdminBar already automatically adds "padding-top: [Admin Bar height in px]" to the <html> element, so this feature mainly applies to elements with "position: fixed". Assuming that Admin Bar is displayed and is 100px tall at the moment, the following markup... <div data-adminbar-adjust="top max-height"></div> ... would result in this: <div style="top: 100px; max-height: calc(100% - 100px);" data-adminbar-adjust="top max-height"></div> Thanks to @Fokke for the idea 🙂
  16. 1 point
    I think we might have a problem here, boss. Is login screen suppose to look like this in version 0.6.2? Version 0.6.1 looks ok (minus the notification bar covering input fields). I have the same results on two installments (pw 3.0.123, firefox 70 and Chromium) one was an upgrade from 0.5.4, second clean install.
  17. 1 point
    Just added support for sending variables to getByName() // RockTabulator grid setup, eg dogs.php $dogs = new RockFinder2(); $dogs->getByName('animals', ['type' => 'dog']); $grid->setData($dogs); // finder setup, eg animals.php if(!$type) $type = "cat|dog"; $rf = new RockFinder2(); $rf->find("template=$type"); return $rf; Also added a simple orGroups() method (see https://github.com/processwire/processwire-requests/issues/331😞 $rf = new RockFinder2(); // setup selector $selector = ['parent' => '/foo/bar']; if($from AND $to) { // show items that are not in the future $selector[] = ['date_start', '<', $to]; // show items that ended this year or not yet $rf->orGroup($selector, [ ['date_end', '>=', $from], ['date_end', '=', ''], ]); } ...
  18. 1 point
    Hey folks! I've been a bit quiet here about Wireframe, but the thing is that I've finally got a couple of "real sites" (as in not my own projects) to implement it on, and that has brought up some new requirements and a few issues. I haven't had the time to dig into a whole lot of really new stuff (components and such), but I have made a lot of other updates to the framework. As such, Wireframe 0.6 was released late yesterday. (A release on Friday the 13th, consisting of a total of 13 commits – not being superstitious here.) I've been updating the docs at wireframe-framework.com as well, but some parts remain a bit outdated. A lot of what happened in this version doesn't really affect the use of Wireframe, but some things do – and one change may even break some existing implementations: It used to be possible to set the view file or layout from Controller with $this->view->layout = "some-layout" or $this->view->view = "json". This has been deprecated and removed in favour of a setter/getter API: $this->view->setLayout("some-layout") and $this->view->setView("json"), and getLayout() / getView() for reading the value. In addition to some obvious benefits from type hinting etc. this also makes it harder to accidentally change something when you thought you were just passing a variable to the View 🙂 There are now three ways to perform actions and pass data from a Controller to the View: Controller::init() (triggered as soon as the Controller class is loaded), public methods (which are made accessible in the View as $this->method_name), and a new addition Controller::render() (called right before the page is rendered). In most cases where one might've used the init() method before, render() is a better choice, as there's less chance that code will get executed "unnecessarily". In addition to existing Page::layout() and Page::view() methods there are now specific setters/getters: Page::setLayout("layout-name"), Page::getLayout(), etc. Original "unified setter+getter" methods may actually get removed at some point, as they're often ambiguous and make code arguably less readable. Quite a few other changes as well, some of which improve performance and others that make the API more polished. Some bug fixes too, though those mostly apply to what I'd consider "border cases" 🙂 Here's the full changelog for Wireframe 0.6.0: ### Added - New Page methods Page::getLayout(), Page::setLayout(), Page::getView(), and Page::setView(). - New Controller::render() method, executed right before a page is actually rendered. - New ViewData class for storing (internal) data required by the View class. - New getter/setter methods for ViewData properties for the View class. - New method Wireframe::getConfig() for getting current config settings. - New method ViewPlaceholders::has() for checking if a placeholder has already been populated. ### Changed - Various View-related features moved from Wireframe module and ViewPlaceholders class to the View class. - Removed access to local get* and set* methods via the PHP's magic setter method __set() and getter method __get() in the View class. - Redirect feature no longer fails if provided with a WireArray data type; in these cases the first item is used as the redirect target. - Improvements to PHPDoc comments. ### Fixed - An issue with Config class where the "all directories exist" message was sometimes displayed unintentionally. - An issue where View Placeholder values might've been overwritten because existence of earlier value was checked inproperly. - An issue where empty / null view file would be automatically replaced with value "default". On a related note, for this version I decided to give sonarcloud a try. For those who don't know it, it's a sort of a code quality inspector, and it's free for public projects. It didn't have a whole lot to complain about at this point, but it's good to have some sort of validation in place just in case. I will also be digging deeper into reported "code smells", as some of them definitely make sense to me 🙂
  19. 1 point
    Hi @Hardoman I post you a code example below that works for me since ages and also with recent PW versions. It includes watermarking too! It is called in a custom module and the event is >before "InputfieldFile::fileAdded" <, but you can call it in ready.php too. Hopefully it is of help for you. Otherwise please ask further. :) public function importImage($event) { $inputfield = $event->object; // handle to the image field if(!$inputfield instanceof InputfieldImage) { // we need an images field, not a file field return; // early return } if(version_compare(wire('config')->version, '2.8.0', '<')) { $p = $inputfield->value['page']; // get the page, PW < 2.8 } else { $p = $inputfield->attributes['value']->page; // get the page, PW >= 2.8 | 3.0 (or only from 3.0.17+ ??) } if('images' != $inputfield->name) return; // we assume a field with name: images if('album' != $p->template) return; // don't do it on other pages than archive album $image = $event->argumentsByName('pagefile'); // get the image // prebuild variations // AdminThumb $image->height(260); // AlbumThumbnail $portrait = $image->height > $image->width; $w = 228; if($portrait) { $w1 = intval($w); $h1 = intval(($w1 / 3 * 4) + 38); } else { $w1 = intval($w); $h1 = intval(($w1 / 3 * 2)); } $image->crop("width=$w1, height=$h1"); // Slick-Slideshow $wmPng = $this->pages->get('id=13967')->getUnformatted('watermark')->first()->width(403); // sharpening added, quality from 80 to 90 $master = $image->contain('width=1000, height=700, quality=100, sharpening=none'); $master = $master->pim2Load('full', false)->watermarkLogo($wmPng)->setQuality(100)->setUpscaling(true)->setSharpening('none')->pimSave(); $sizeArray = array(array(448, 336), array(678, 506), array(908, 676)); foreach($sizeArray as $sizes) { $master->size($sizes[0], $sizes[1], array('upscaling'=>false, 'cropping'=>false, 'quality'=>90, 'sharpening'=>'soft')); } // sharpening added, quality from 80 to 90 // prebuild variations // check / import IPTC data $additionalInfo = array(); $info = @getimagesize($image->filename, $additionalInfo); if($info !== false && is_array($additionalInfo) && isset($additionalInfo['APP13'])) { $iptc = iptcparse($additionalInfo["APP13"]); if(is_array($iptc) && isset($iptc["2#025"]) && is_array($iptc["2#025"]) && count($iptc["2#025"])>0) { $tmp = $iptc["2#025"]; $tags = array(); foreach($tmp as $k=>$v) { if(empty($v)) continue; $tags[] = jhpTextConversion(trim(strtolower($v))); } $p->images->trackChange('tags'); // prepare page to keep track for changes $image->tags = implode(', ', $tags); $p->save('images'); // save the page } } // check / import IPTC data }
  20. 1 point
    How do you try to get this image? Doesn't really matter 🙂
  21. 1 point
    You are on the right track. See also here: Are you using tracy debugger? It can help a lot, eg using bd('hook fired'); will show you what's going on in the tracy bar (or using firelogger fl() can also be helpful.
  22. 1 point
    Locate head.inc in your templates directory, and remove the following line (probably line 67) from it: $children->prepend($homepage); Should do the trick. It's always good to read through the files, they contain a lot of informative comments to get you started.
  • Create New...