Jump to content

kongondo

PW-Moderators
  • Posts

    7,379
  • Joined

  • Last visited

  • Days Won

    139

Everything posted by kongondo

  1. Hi all, I wanted to update you on the progress of the next MM as discussed from this post onwards. Here's a very short preview of the next MM. It is still very early days. Nothing is polished and things may change. My main focus is on the functionality although I spent a bit of time on the GUI. I have spent considerable time thinking about the conceptual design, especially for the API and I am quite pleased with that so far. Before you ask, I don't know when this will be ready. It is not a small re-write. I do know that it won't be until after the summer though, that's for sure. Happy to get early feedback, thanks. MM Next Early Preview Demo 1.mp4
  2. @fruid, True. This is planned for the next version of MM (see this post). I'll post a demo of it here later today. There is no firm ETA for its release but it will be after summer most likely.
  3. Hi @fruid, Do you mean when viewing the media in Media Manager? If yes, that is not currently possible. What's your use case? I'll have a think about this.
  4. Hi @Boost, Are you able to install other modules by uploading their zip files? If not, I am thinking is a permissions issue in your system?
  5. Is your issue resolved then? I see your edit as well but I am still confused.
  6. That's exactly what I said wouldn't work 🙂. You cannot control non-native children. If the children are MB (drag and drop) children, they are always shown (unless you disable them in the backend using the disable menu item option). I don't understand what you mean by 'not really working'. A little more detail would help.
  7. What @flydev said. A slightly different alternative to the above is to store the order values in a hidden input as a CSV. In that case, you don't need to touch window.location.href. You would use the values in the CSV to access the GET params sequentially.
  8. @bernhard Very late comments here. I'd started watching but things got in the way and I didn't finish. I've just finished watching. A-M-A-Z-I-N-G! Thoroughly enjoyed this one. Thanks for sharing and thanks for representing ProcessWire. It looks like a lot of thought went into the presentation. It was also interesting to hear about your background. I am guessing this perhaps explains why your work/modules are always so polished and of high quality!! I suppose you don't get into a helicopter without meticulously checking everything works as it should 😀. I liked the way you showed the basics first and gradually moved into the more advanced topics. I also liked the way you used git history. I have learnt some new things as well and my interest is piqued. I have never been a fun of PHP template engines but that latte stuff you showed got me really interested. That is a lot like 'modern-js' like you said! Have you noticed any performance issues with latte? I was also very impressed with ddev. I know you have mentioned it before but the 'docker' bit is what has put me off in the past. For some reason, docker was either slow on my machine (a Windows thing maybe?) or just wouldn't work. I am very curious about ddev now. Do you still use a Windows machine? How's ddev in terms of performance? Anyway, great stuff and thanks again for sharing!
  9. Hi @Roych, There is no setting for this currently. 'include_children' applies to only to the 'real/natural ProcessWire children pages. For instance, if my ProcessWire page tree is as follows: Home About History Mission Team Services Plans And your Menu Builder Menu is as follows (in the backend): Home About Services If you use 'include_children', your rendered menu will display as follows: Home About Services History Mission Team As you can see, 'include_children' will grab the 'real' children (ProcessWire pages) of 'About' and display them in the menu. However, without 'include_children', your menu will be rendered as follows: Home About Services You cannot programmatically disables 'Services' from not showing. I.e,, there is no option for you to get: Home About However, you can achieve what you want by using getMenuItems() You can have getMenuItems() return an object (WireArray). You can then use WireArray methods to remove children items from the WireArray. Finally, given that this is a single level menu, you can just loop through the filtered WireArray and display them in your markup. Example code (untested): <?php namespace ProcessWire; $menu = $modules -> get('MarkupMenuBuilder'); // get the menu items for menu with ID 1030 /** @var WireArray $menuItems */ $menuItems = $menu->getMenuItems(1030); // OR, if passing options // $menuItems = $menu->getMenuItems(1030, 2, $options); // ------ // grab top level menu items only // they do not have a parent, i.e. parent_id == 0 /** @var WireArray $topLevelMenuItems */ $topLevelMenuItems = $menuItems->find("parentID=0");// you could also use (destructive) filter $out = "<ul>"; foreach($topLevelMenuItems as $topLevelMenuItem){ $out .= "<li><a href='{$topLevelMenuItem->url}'>{$topLevelMenuItem->title}</a></li>"; } $out .= "</ul>"; Hope this helps.
  10. Thanks for reporting @gebeer. Added to my TODO.
  11. Hi @Pretobrazza, Currently this is not possible but will be possible with the next version mentioned in this post above. Best
  12. @alexm. This one's a mystery. It works here just fine. I'll check what my server environment is for the demo to see if that sheds any light.
  13. @alexm, Try: <?php namespace ProcessWire; $formattedCurrency = str_replace(" ", "", $formattedCurrency);
  14. You can cherry pick what tables to backup up, e.g. 'pages', 'field_body', 'field_images', 'templates', etc. If the MM fields are empty you need to find the connection between the production 'usual pages' with MM fields and the corresponding staging 'usual pages' with MM fields. Given that you used an import, similar to above assumptions, their titles and names will (should) be identical, but their IDs will be different. Hence: Production A Usual Page -> exported to staging Title: My Usual Page Page ID: 1450 Name: my-usual-page mm_field (WireArray of WireData where each WireData has a property id, i.e. $mmObject->id == 1234) Staging A Usual Page <- imported from production Title: My Usual Page Page ID: 1876 Name: my-usual-page mm_field (WireArray of WireData BUT EMPTY -> SO NO values for mm_field) Production and Staging 'usual pages' are connected via 'names'. So... Staging: Use findRaw or Loop through imported staging pages. Save their names and IDs in an array. Staging: Prepare an OR (piped) selector string of $namesPipedSelectorString from #1 Production: Use findRaw with $namesPipedSelectorString to find the ids, names and mm_fields values in the corresponding pages in production. Production: Prepare the IDs of the mm_fields in #3 as $idsOfMMPagesInMMFieldPipedSelectorString. If you use findRaw, this will be in the array column 'data'. These are the page IDs of the MM pages in production. Production: Use $idsOfMMPagesInMMFieldPipedSelectorString in a findRaw to get the names of the MM pages in production. Prepare these in an array of $namesOfMMPagesPipedSelectorString. d Staging: Use $namesOfMMPagesPipedSelectorString from #5 in a findRaw() to find the page IDs of the corresponding MM pages that were created when you imported from production. In other words, the MM pages in #5 and #6 are identical, expect for their page IDs. Production & Staging: Prepare an array that contains the names of the exported usual pages, the IDs of the imported usual pages (the ones with empty MM fields), the page IDs of the MM pages in #6. Your connection is complete. You now know the IDs of the MM pages and their corresponding usual pages where they need to be references in the MM fields. Staging: Loop through newly imported pages and use the array in #7 to populate the empty MM fields. I.e., in the loop, when you get to a page, e.g. 'my-usual-page', using the array in #7 find the page IDs of the corresponding MM pages. Use each of those to create a WireData object that you add to the WireArray mm_field. Pseudo code below (not tested): <?php namespace ProcessWire; $importedUsualPages = $pages->find("your-selector"); $arrayOfConnections = [ 'my-usual-page' => [ 'id' => 1876, 'imported_mm_pages_ids' => [2035, 2036, 2038, 2056] ] ]; foreach($importedUsualPages as $importedUsualPage){ $importedUsualPage->of(false); $mmField = new WireArray(); $importedMMPagesIDs = $arrayOfConnections[$importedUsualPage->name]; foreach($importedMMPagesIDs as $importedMMPageID){ $mmFieldItem = new WireData(); $mmFieldItem->id = $importedMMPageID; $mmFieldItem->type = 3;// 1-audio; 2-document; 3-image; 4-video // add MM item to WireArray $mmField->add($mmFieldItem); } // ----- // populate mm_field of page $importedUsualPage->set('mm_field', $mmField); $importedUsualPage->save('mm_field'); } Hope this helps. Let me know how it goes.
  15. Hi @alexm, That's correct. PadloperProcessRenderOrders renders the GUI. It has lots of hookable render methods. For instance, in demo-2, we hook into PadloperProcessRenderOrders::getSingleViewTableRow (line#29 ) to display the details of the 'customise' text field for the line item. The hookable methods are not yet documented (sorry). Please find them in that file and inject your markup using one of the hooks. Let me know how you get on.
  16. I think you are right. It sounds like the import for the media pages themselves (i.e. the media manager pages) worked. However, these were created as new pages using the template 'media-manager-image'. On the other hand, the 'usual' pages with FieldtypeMediaManager field perhaps also got their values imported. One of the values they hold is the page ID of the page where the media (in this case image) really lives. So, in the production site one value could be 1234. However, the newly created page in the staging could have been created with a page ID 5623. This means that if by coincidence some IDs are identical between the sites, you might get MM images showing up in the wrong pages 😀. Back to your script. You need to find a connection between production 'media manager pages' (i.e. the pages that use the template media-manager-image) and the staging usual pages media manager fields. The connection between them that has not changed is the page name of the media manager pages, i.e. Production MM Page Title: My Awesome Image Page ID: 1234 Name: my-awesome-image Page with MM Field A Frontend Page with a Gallery showing some MM Images in an MM Field MM Field (WireArray of WireData where each WireData has a property id, i.e. $mmObject->id == 1234) [see the docs]. Staging MM Page Title: My Awesome Image Page ID: 5623 Name: my-awesome-image Page with MM Field A Frontend Page with a Gallery showing some MM Images in an MM Field MM Field (WireArray of WireData where each WireData has a property id, i.e. $mmObject->id == 1234) <- it points to the old value in the production site. As you can see, the common things between the two sties is the name/title. One (rather convoluted way) to go about it is (written in browser, not tested and only quickly thought through). Get the values of the $mmObject->id in your 'new pages [the imports]', i.e., the value 1234 in our example. You could loop through each of the staging pages or just grab them all using findRaw("template=your-template",['id','mm_field']); Process the the above array to get all the 'data' values in the 'mm_field'. Keep this one one array. Use the ids you have collected in #2 and do a findRaw in the production site (implode the IDs so you get 1234|1345|4356, etc). What you want are the names, so findRaw("id=$ids,check_access=0",['id','name']); #3 Will give you the names and IDs of the MM pages in Production. Prepare these names for an OR selector string similar to what you did with $ids in #3. Use the $names selector string in #3 to find the corresponding MM pages in the staging site, i.e. findRaw("name=$names",['id','name']); You will end up with two arrays, one for production and one for staging with values $productionArray = [1234=>'my-awesome-image'] and $stagingArray = [5623 => 'my-awesome-image']. You can process this two arrays so that you end up with $processedArray = [1234 => 5623, etc] Loop through the newly imported pages in staging, loop through their MM fields and replace 1234 with 5623. OR simply... Install ProcessDatabaseBackups in the production site Export the site usign ProcessDatabaseBackups Install ProcessDatabaseBackups in the staging site Use ProcessDatabaseBackups to backup the current DB in the staging site Import the exported db from production (#2) into the staging site using ProcessDatabaseBackups Copy the assets from production site into staging site Test Done 🙂
  17. Hi @alexm, That's interesting. I am not seeing the space in my local dev nor in the starter demos. However, I am seeing it on the demo site as you point out. Not sure what's going on there. I know the demo site's Padloper is a bit old but that wouldn't be your case. PHP version differences? Meanwhile, maybe try and remove the space post the fact (str_replace())?
  18. @alexm,Glad you got it sorted! Aren't these conditions resulting in the same thing?
  19. Hi @sodesign, It is not clear to me what you mean by 'media-manager-image field'. Do you mean images in a FieldtypeMediaManager/InputfieldMediaManager field on a 'usual' ProcessWire page or are you talking about the actual image field (media_manager_image) that holds the images for media items in media manager pages (which live in /admin/media-manager/...)? Are the staging and production sites on the same server?
  20. Hi @alexm, Thanks for clarifying. I get you now. Although the those hooks would normally work, since the form in cart-edit is being submitted to a 'virtual' URL handled by URL Hooks and because a redirect occurs, execution halts, hence, the 'hooks' get released/discarded and you are left with nada. If anyone knows if my statement is untrue or partially incorrect, please let me know. Now, back to your issue, easiest solution is to handle updating the cart yourself using $padloper API instead of sending the form (action) to the virtual padloper URL. This will allow you to process your custom form inputs yourself. Updating the cart is as simple as this: <?php namespace ProcessWire; // *** UPDATE CART FOR AN EXISTING CART ITEM *** // @note: $id: this is the id of this product as a cart item in the database // it is not the page ID of the product! // @note: these inputs should match the fields in your custom 'cart-edit' form $id = (int) $input->post->padloper_cart_update_product_id; $quantity = (int) $input->post->padloper_cart_update_product_quantity; // update the cart ($key=>$value pair of cartItemID => cartItemQuantity) $updatedCartProduct = [$id => $quantity]; // update the cart $padloper->updateCart($updatedCartProduct, $rem_products = null, $isRedirect = false); // handle your custom form input $discountCode = $sanitizer->text($input->post->discount_code); // ETC... Your and PadloperCart::getProductPrice', null, 'discountCodePrice' Hook doesn't need changing. Hope this helps. Please let me know if you need further help with this.
  21. Hi @alexm, I have tested and it works for me with hook, hookBefore and hookAfter, i.e. all the below work (in ready.php): <?php namespace ProcessWire; // $this->addHookBefore('Padloper::updateCart', null, 'updateCartHook'); $this->addHookAfter('Padloper::updateCart', null, 'updateCartHook'); // $this->addHook('Padloper::updateCart', null, 'updateCartHook'); However, it is not clear to me how hooking into Padloper::updateCart helps with what you are trying to achieve. 676 in the example above is the cart_row_id of some product and 6 is the quantity of the product in the cart. What information about the cart are you after in relation to your discount?
  22. Others have mentioned how to do it in the Markup or in $config. If you wanted to do it using JS, this is how: document.body.addEventListener("htmx:configRequest", (event) => { // add XMLHttpRequest to header to work with $config->ajax event.detail.headers["X-Requested-With"] = "XMLHttpRequest" }) https://htmx.org/events/#htmx:configRequest Not meaning to hijack this thread and I haven't read through everything and I don't know how Markup Regions work...just want to mention that I have set up a GitHub repo for htmx + Alpine.js + Tailwind CSS + ProcessWire demos. It is early days but I am hoping to add all sorts of demos there, from basic to advanced ones, including backend and frontend examples. I'll create a thread for this work at a later time. Meanwhile (and I have nothing against the OP wish), I am happy to take on a challenge like 'how would you build this complex page using htmx' . OK, maybe not as complex as this app: From React to htmx on a real-world SaaS product 😁: (too much todo, etc.). Edit First two demos are discussed in this thread:
  23. Glad it worked! That's strange. Are the options definitely sent to the browser? That's line #138 here in /demos/demo_alpine_renders_modal/products-alpine-renders-modal.php . If you dump $allProductsVariants here in line #96, do you get anything?
×
×
  • Create New...