Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 03/14/2019 in all areas

  1. I've just upgraded the forums to the latest version 4.4.x as there was a critical security patch that warranted it. As usual, there is some pain in upgrading from a 4.x to 4.x branch due to template changes and feature changes/additions so you may find things have moved around a bit. There is still work to do on the template as this was a little rushed (security update forced my hand) but it should be functional at the very least. If you spot anything drastically broken that I may have missed, please let me know here. Minor template tweaks (fonts, alignment etc) will be updated in the next few days.
    11 points
  2. This is all @tpr's hard work - he has just added a search/filter implementation using his awesome filterbox.js - be sure to check it out and Star it! Note that in addition to filtering, if you hit "Enter" it will load the first matched file. Thanks again Roland - this is very cool!
    5 points
  3. @jploch AFAIK, you can turn off PCRE JIT compilation if needed. Some info in the discussion here.
    3 points
  4. Thanks @adrian, I was really missing these features (search and recents list). It was a challenge to set up FilterBox to fit in here but fortunately everything fell into place.
    3 points
  5. Hi @louisstephens, <link rel="icon" type="image/png" href="<?php echo $config->urls->templates?>favicon.png" /> There is no need to add a splash before favicon.png. Gideon
    3 points
  6. I'm glad lots of you like this tip. In the meantime I found more to read: https://codequs.com/ has lost of recent articles on web development. About pure JavaScript I found these one to be interesting: Do we still need JavaScript frameworks? Quote: "That said, much of what frameworks do will probably become easier to do with smaller libraries and/or native code as time goes on. Take my application as an example. At the same time, if the large frameworks and libraries remain versatile they may morph, adapt, and stick around. If not, they may end up like jQuery — a tool of the past for the most part." https://codequs.com/p/r1Jzty4S4/do-we-still-need-javascript-frameworks Design Patterns: The Comprehensive Guide to JavaScript Design Patterns https://codequs.com/p/B1lboCPS4/the-comprehensive-guide-to-javascript-design-patterns A guide to prototype-based class inheritance in JavaScript https://codequs.com/p/HyiztJFH4/a-guide-to-prototype-based-class-inheritance-in-javascript Prototype-based Inheritance and Prototype chain in JavaScript (ES5) https://codequs.com/p/Hy6_WgCI4/prototype-based-inheritance-and-prototype-chain-in-javascript-es5 JavaScript ES6 Classes https://codequs.com/p/H1poPtiS4/javascript-es6-classes Javascript and Functional Programming: An Introduction https://codequs.com/p/BJL08ThSV/javascript-and-functional-programming-an-introduction State management patterns in JavaScript: Sharing data across components https://codequs.com/p/HkD3mZ9LE/state-management-patterns-in-javascript-sharing-data-across-components "Tips" JavaScript naming conventions: do’s and don’ts https://codequs.com/p/B1-VWxRIN/javascript-naming-conventions-do-s-and-don-ts 12 Concepts That Will Level Up Your JavaScript Skills https://codequs.com/p/BkdaLTnS4/12-concepts-that-will-level-up-your-javascript-skills Understanding the Spread Operator in JavaScript https://codequs.com/p/ByL0qvXUV/understanding-the-spread-operator-in-javascript The Complete Guide to Loops in JavaScript https://codequs.com/p/S1dZcv7LN/the-complete-guide-to-loops-in-javascript Memoization is an optimization technique that speeds up applications by cached result https://codequs.com/p/H1XlyssUE/understanding-memoization-in-javascript Arrays: How to Sort an Array of Objects in JavaScript https://codequs.com/p/BysEP63SV/how-to-sort-an-array-of-objects-in-javascript 2 Ways to Merge Arrays in JavaScript https://codequs.com/p/H1jReV-IN/2-ways-to-merge-arrays-in-javascript How to Deep Clone an Array in JavaScript https://codequs.com/p/rynJIss84/how-to-deep-clone-an-array-in-javascript 4 Uses of JavaScript's Array.map() You Should Know https://codequs.com/p/B13x_ZqLE/4-uses-of-javascript-s-array-map-you-should-know Asynchronous tasks: Understanding Promises in JavaScript https://codequs.com/p/Sy3hiPP8N/understanding-promises-in-javascript JavaScript Promises: The Definitive Guide, Part 1 https://codequs.com/p/BkToHnnU4/javascript-promises-the-definitive-guide-part-1 Introduction to fetch() https://developers.google.com/web/updates/2015/03/introduction-to-fetch How to Use the JavaScript Fetch API to Get Data https://scotch.io/tutorials/how-to-use-the-javascript-fetch-api-to-get-data
    3 points
  7. Don't shoot the messenger – I know this is from WordCamp, not ProcessCamp, but there's plenty of quality material there not strictly tied to WordPress ? https://wpwoofi.com/wordcamp-nordic-paneelit-2019/ Sadly the recording misses the beginning of the UX for everyone talk by Piccia Neri. This was my absolute favourite in the whole event, there were so many good points there. She has the ability to explain scary-sounding concepts and processes in a way that makes them really easy to grasp, and actually makes them seem attainable even in relatively low-budget projects ? "Lessons from WordPress core on how to (not) write code" has some good pointers for anyone designing dev tools, "Cache is keeping you from reaching your full potential as a developer" contains valid arguments, and although "Continuous integration and deployment with WordPress" is definitely WP-specific, the basic principles can be easily applied to other platforms as well. Just to mention a few. Anyhow, I hope someone finds these interesting ?
    2 points
  8. 2 points
  9. Glad it all worked out - we've all done similar things ?
    2 points
  10. Back here with... quite an amount of shame... I'm sorry I have taken time from you all. Here's the thing : my site/ready.php which I thought did not have access to bd() because I couldn't even see a simple bd('ok'); was not at the right place. A bell just rang in my head a few minutes ago after making a fresh re-install of a blank profile ! I came back to my original local site and thought : "No way, Fred ! site/ready.php NOT your-website-root/ready.php !!!!" I moved ready.php and.... tada ! (Of course...). What a nerd... So again, SORRY for having taken some of your time, but thanks for your helpful answers. I still have learned quite a lot from our exchange and that is the most important thing. I'm glad I posted in 'Getting started' ;)
    2 points
  11. I remember falling into the same trap. I didn't modify the generated config.php but simply moved the contents from the unzipped subdirectory one up before I submit the database information.
    2 points
  12. Color for "ipsMessage ipsMessage_info" class is old:
    2 points
  13. Thanks Pete! Avatars are also stretched in the Notifications panel. Another thing I noticed is that all out locations have "Location" prepended - eg: "LocationBuckley, Wales"
    2 points
  14. Yep, spotted those so will look into them as I get time.
    2 points
  15. Something looks wrong here. The avatars in the Latest Topics column are stretched out vertically. Also the whole Latest Topics column has moved upwards out of line with the Welcome to Processwire column.
    2 points
  16. 2 points
  17. @SamC: Exactly @happywire: You are completely right except the last point: The snippet performs the boolean evaluation of Math.random() some thousend of times: var YesIfTrue = !!~~(Math.random() * 2); // Boolean result 50/50 You either get a boolean true or boolean false for each iteration. YesIfTrue is set, if the truncation of (Math.random() * 2) is equal or above 1.0 (or Math.random() returns a value equal or above 0.5). The less obfuscated version of that line would be: var YesIfTrue = Math.random() >= 0.5; Which can be unrolled to: var YesIfTrue; if(Math.random() >= 0.5) YesIfTrue = true; else YesIfTrue = false; which is what actually happens behind the scenese: A numerical comparison on two floats along with a "jump" to either assignment statement. While there still is some "jumps are bad" in many minds, that's not necessarily true for JavaScript. In fact the version using the comparison may effectively execute faster than the obfuscated "true boolean" version, but the unrolled version is slowest (10Mio iterations, Firefox 65): True Boolean: Yes: 4999123 No: 5000877 in 54ms Logical: Yes: 9997660 No: 10002340 in 51ms Comparison: Yes: 14996131 No: 15003869 in 39ms Unrolled: Yes: 19995907 No: 20004093 in 98ms Floor: Yes: 24996634 No: 25003366 in 57ms var i, cntYes=0, cntNo=0; var tStart, tEnd; tStart = window.performance.now(); for(i=0; i<10000000; ++i) { var YesIfTrue = !!~~(Math.random() * 2); cntYes += YesIfTrue; cntNo += !YesIfTrue; } tEnd = window.performance.now(); console.log('True Boolean: Yes: '+cntYes+' No: '+cntNo+' in '+(tEnd-tStart)+'ms'); tStart = window.performance.now(); for(i=0; i<10000000; ++i) { var YesIfTrue = ~~(Math.random() * 2); cntYes += YesIfTrue; cntNo += !YesIfTrue; } tEnd = window.performance.now(); console.log('Logical: Yes: '+cntYes+' No: '+cntNo+' in '+(tEnd-tStart)+'ms'); tStart = window.performance.now(); for(i=0; i<10000000; ++i) { var YesIfTrue = Math.random() >= 0.5; cntYes += YesIfTrue; cntNo += !YesIfTrue; } tEnd = window.performance.now(); console.log('Comparison: Yes: '+cntYes+' No: '+cntNo+' in '+(tEnd-tStart)+'ms'); tStart = window.performance.now(); for(i=0; i<10000000; ++i) { var YesIfTrue; if(Math.random() >= 0.5) YesIfTrue = true; else YesIfTrue = false; cntYes += YesIfTrue; cntNo += !YesIfTrue; } tEnd = window.performance.now(); console.log('Unrolled: Yes: '+cntYes+' No: '+cntNo+' in '+(tEnd-tStart)+'ms'); tStart = window.performance.now(); for(i=0; i<10000000; ++i) { var YesIfTrue = Math.floor(Math.random() * 2); cntYes += YesIfTrue; cntNo += !YesIfTrue; } tEnd = window.performance.now(); console.log('Floor: Yes: '+cntYes+' No: '+cntNo+' in '+(tEnd-tStart)+'ms');
    2 points
  18. Wow, there's some really great replies here, thanks everyone ? For clarity, the context is 'this' (quite literally): http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/ That line came from this section on the page: 3. Fix this when method is assigned to a variable So what I've read previously in this thread and about bitwise OR, is this what happens? // Let's forget about the + 1 -1 stuff for now // Math random returns a float between 0-1 (not inclusive of 1) var randomNum = ((Math.random() * 2 | 0); // Once this float is multiplied by two (keeping the decimal places shorter) var randomNum = (1.6 | 0); // After forced type coercion to int and trucation (because of bitwise OR) var randomNum = (1 | 0); // Binary values are compared // Bitwise OR: 1 compared to 0 = 1 var randomNum = 1; // OR var randomNum = (0.7 | 0) // After forced type coercion to int and trucation (because of bitwise OR) var randomNum = (0 | 0); // Binary values are compared // Bitwise OR: 0 compared to 0 = 0 var randomNum = 0; Just did a super quick demo to try and solidify this in my head, if you don't use vscode and quokka plugin, try it, it's awesome ? @happywire if you're just starting out with JS, I can highly recommend this course: https://www.udemy.com/understand-javascript/ Anthony is an incredible teacher. This isn't just your usual "make a project with me" i.e. just code along, finish the project, learn next to nothing and not be able to implement anything you've learned in different scenarios kind of course. This is much more about the theory of how JS works.
    2 points
  19. Ha, thx heaps for the detailed reply. As you can see I understood it wrong and thank you for getting back about it. Much appreciated! So, I am just learning JS basics (doing this course at the moment udemyDOTcom/javascript-bootcamp-2016/ ), and to clarify/repeat, what is happening here is called type coercion as explained here for example https://eloquentjavascript.net/01_values.html#h_AY+YGu6qyM , right? Integer is a full number, so no comma behind it, in this case either 0 or 1. Since Math.random outputs floating numbers, meaning with comma and lots of numbers behind the comma, then those numbers, the decimals, are just cut off, truncated, like you say. Then you say this and I think this is highly important to understand because no method is called. So instead of converting the floating result with Math.floor one can just use the logical operator to get an integer, right? The snippet shows how many times from 10'000 runs Math.random() outputs a true integer without type coercion and how many times it outputs a floating number, right?
    2 points
  20. Thank you all for this little lesson ?
    2 points
  21. sorry: No! Any logical operation like OR '|', AND '&', EXOR '^', Bitwise complement '~' or even shift can only be processed on integers. Using one of these operators enforce JavaScript to typecast any other type into integer. If one of the operators is a float (like return value of Math.random), then decimals are just truncated (a 1.99999 gets 1), if its a string, JS tries to convert it into an integer first. The logical OR (in contrast to the boolean OR '||') is executed in any case. Even if '| 0' does not seem to make any sense, its just there to enforce the type conversion, so the result is an integer. Using a logical operator in contrast to Math.floor basically optimizes for performance (no method call). And if you need a true boolean result and love obfuscated code, try this: var randomNum = !!~~(Math.random() * 2); Maybe this snippet helps to clarify it: var i, cntYes=0, cntNo=0; for(i=0; i<10000; ++i) { var YesIfTrue = !!~~(Math.random() * 2); // Boolean result 50/50 cntYes += YesIfTrue; // Count only true results cntNo += !YesIfTrue; // Count only not true results } console.log('Yes: '+cntYes+' No: '+cntNo);
    2 points
  22. The hook code definitely needs to be in /site/ready.php or /site/init.php. It won't work in your template-prepended _init.php file - the page is already rendering by the time that code executes.
    2 points
  23. We have a fairly simple website: www.labsphere.com It was developed in 2015/2016 by a contractor who did a great job of capturing what we needed. We are happy with his work and the site has been great, though we are also looking at replacing the site within the next year just to keep our brand fresh. The problem is, we have no one on staff that can manage the site beyond very basic Processwire CMS (add pages, add images, add text, etc). The original contractor who developed our site is available when we need him to make changes, but for business integrity purposes we need to have a second person or agency with access to our site as a backup. If the original developer wins the lottery and no longer wants to work on websites, we need someone on staff who could assist with issues. My goal would be to find someone who can act as a backup for when the original developer may be too busy to assist with issues. Maybe a monthly retainer could be paid for someone to "be on call" for times when we want to change something? Let me know if you are interested or have any questions. Thanks, Darlene Delano 603-731-4916 ddelano@labsphere.com
    2 points
  24. You are right. I am not referring to the website. However, you might need certain aspects of your products to be multilingual, for instance, their categories/collections, descriptions, etc. Padloper needs to make sure that the developer/shop owner has inputs corresponding to the languages they have installed for entering information. In my example above, if you had a product "Trousers" and your shop is in Canada, you probably have an English and a French version of the site. Padloper needs to give you inputs for both when you are creating product categories, tags, or inputting product titles, descriptions, etc. Maybe you are thinking about old Padloper ? :-). Exactly.
    2 points
  25. @louisstephens In that thread you linked I found and since I cannot edit my above post I meant that in fact the source from the later , "srcset, sizes and picture support" uses art direction instead of sizes and dpi, however I also read through the MarkupSrcSet thread and it does not seem correct to me at least, however I might be able to look into that repo to learn how image variations are created server-side so that I can have an image array to work with without affecting the frontend. If you are unsure, test the output with https://ausi.github.io/respimagelint/ it is the definite answer to having correct syntax when it comes to responsive images, be this using art direction or sizes.
    1 point
  26. Thats fine with me. If I use Mamp with PHP 5.6 this issue is solved. No worries! Keep up the good work! Looking forward to use this one day ? I still have no clue what stops the markup regions from working though.
    1 point
  27. Sorry dude, I am aware of this issue but forgot to update the first post and the github doc. So yes, basically, In the last version of Duplicator, its necessary (but unwanted) to move the unzipped data to the parent dir.. And about your last issue, try what its said in the github issue linked by @netcarver and more precisely this one : https://github.com/composer/composer/issues/7836#issuecomment-452341683 And just saying, I have not tested the module with PHP 7.x and it might have some issues on this version. sorry for the inconveniences, I hope to get the time to finally work on the V2 ? but I promise you guys to take a look at the actual version and make a revision in the last 10 days or ask to moderators to ban me from the forum ! ? ?
    1 point
  28. Hi. Please PM @Pete, the forum admin. Maybe some settings got mucked up. Sorry.
    1 point
  29. I changed the PHP version to 5.6 and these errors are gone now. However my markup regions seem not to be working. But when logged into the admin everything on the frontend works fine. When logged out I get an error saying "no regions" and the site is messed up. Iam about to give up on this and just use the site profile exporter for now ?
    1 point
  30. You mean something like this? $content = $page->images; if (count($page->images)) { // the page has one or more images foreach ($page->images as $image => $value) { $content .= $value; $content .= "picture markup to follow.."; } }
    1 point
  31. I had the same problem a couple of times now. For example when I try to install a backup of a live site on my localhost (Running on Mamp) or an a web server I always get the error config file cannot be found. The issue happened in the installation process after entering the database data and proceed. Maybe this is happening when the website is in another subdirectory and not the web root? The duplicator always makes a subdirectory when unzipping the files and then looks for the config in the root folder. After I manually change the config file, the site was showing up and I could see all the content in the admin, but had some strange errors on the frontend.
    1 point
  32. Soma and Robin S are missing their avatars - I am sure there are many more also.
    1 point
  33. Looking nice even in its unfinished state :-). One thing now that we have you here (I think I might have asked this before), you know when one is browsing list of unread posts/content, we used to be able to hover on a topic's title in the list and click a button/link to mark that AND ONLY that post as read. That was a time saver! There are times when you just want to mark A FEW/SOME posts as read without actually opening them (?). Are you able to look into this please? Thanks!
    1 point
  34. Edge (still same machine): True Boolean: Yes: 4998588 No: 5001412 in 3542.50002880837ms Logical: Yes: 9999775 No: 10000225 in 3009.699778367602ms Comparison: Yes: 14999604 No: 15000396 in 3001.5002759201707ms Unrolled: Yes: 19998134 No: 20001866 in 3037.500176051153ms Floor: Yes: 25002010 No: 24997990 in 4482.999860439448ms
    1 point
  35. The thread finally switched into Browser Benchmarking now. My numbers were taken from Firefox, which returns now as an integer only. On Vivaldi (Chromium) this is a float and execution times are generally longer (same machine) and Logical indeed is fastest: True Boolean: Yes: 5001949 No: 4998051 in 201.30000000062864ms Logical: Yes: 10001446 No: 9998554 in 173.00000000250293ms Comparison: Yes: 15001053 No: 14998947 in 177.5999999990745ms Unrolled: Yes: 20000397 No: 19999603 in 240.49999999988358ms Floor: Yes: 24999139 No: 25000861 in 186.0999999989872ms So watch your step when optimizing for performance in JS.
    1 point
  36. I get different results: So for me the logical was the fastest ? Second try:
    1 point
  37. @Autofahrn that last post was awesome!
    1 point
  38. @adrian Thank you for all the usefull informations! You were right, apache was using the old version, I had to update it with: sudo a2dismod php5 sudo a2enmod php7.0 sudo service apache2 restart Do you have any suggestion on other types of testing environemnt than the one I have cited above? Is it possible working on the same repository, to both update a testing environment + local database and the live version + live database? (obviously after pushing to git in my case).
    1 point
  39. Sorry, I wasn't suggesting setting everything up again - just a clean PW install with no modules, pages, templates etc just to see if it works. I imagine it will, but thought it might be a good sanity check in case there is some weird server setting somehow interfering - although I can't imagine what and you mentioned that you tried on your local dev as well and it still doesn't work.
    1 point
  40. https://flaviocopes.com/page/ebooks/ I am in the middle of reading his The JavaScript Handbook which is great to get up to speed in the additions of the language added in the last few years. This is a no-nonsense, easy to understand, from-a-programmer-to-programmers book, highly recommended ? All six titles: The JavaScript Handbook (171 pages) JavaScript from ES5 to ESNext (84 pages) The React Handbook (220 pages) The Node.js Handbook (189 pages) The Express.js Handbook (61 pages) The Vue.js Handbook (122 pages) Happy coding ?
    1 point
  41. Looks fine, if you inspect the source code you will see the XML markup. This is not a sitemap for users, but one you can submit to search engines, see here: https://support.google.com/webmasters/answer/183668?hl=en Here is a quick how-to, i did not find this feature in the docs: Create a new field of type "FieldsetTab", e.g. "Seo Settings" Use this field to group other fields that should be displayed in the new tab A screenshot is probably easier ?
    1 point
  42. I agree, Padloper should work the Processwire way, that's the whole point of it. Using multi-language fields and page objects for products is the way to go. I guess most of us who builds a PW store will expect it that way.
    1 point
  43. Well darn, I set $config->advanced to true, and nothing seems to be changing for me on the field settings. Is there something else I need to change out? That was completely my fault. I changed a config in the wrong folder without thinking. Thanks adrian, that solved the issue.
    1 point
  44. Hello, I support this: In other words I think supporting multilingual stores is a must and doing it the PW way is the easiest to use by those who will build stores based on Padloper 2. Regarding performance, custom db tables might have an advantage but – I guess – most Padloper 2 sites will never reach the point when it matters.
    1 point
  45. To see all the places where a particular method is called by the core you would need to search the core code. In the case of Fieldtype::getInputfield the most significant places are in Field::getInputfield, which returns the inputfield according to the fieldtype of that field, which in turn is called by Fieldgroup::getPageInputfields, which loops through all the fields that belong to a fieldgroup (you can think of a fieldgroup as being sort of the same as the template) to get and populate their inputfields so they can be displayed in Page Edit (for instance). But you probably don't need to spend time working through all of that in order to successfully create a Fieldtype module. An important thing to understand if you don't already is that your Fieldtype module extends the Fieldtype class. This is called Object Inheritance: http://php.net/manual/en/language.oop5.inheritance.php So all the methods in the Fieldtype class also belong to your module, and the code for those methods is what you see in Fieldtype.php unless you override the method by including it in your module. To illustrate with an example, we can see that Fieldtype::getBlankValue returns an empty string: https://github.com/processwire/processwire/blob/cbfe97de207e3166451f16865429c02c081791e8/wire/core/Fieldtype.php#L494 If we look at FieldtypeText we see that it doesn't include a getBlankValue() method - it doesn't need to because the getBlankValue() method of Fieldtype already returns the right value for a blank text field. But if we look at FieldtypeCheckbox we see it does include a getBlankValue() method - that's because an empty string isn't the right type of value for a blank (unchecked) checkbox, so it implements its own method to return 0.
    1 point
  46. @tiefenbacher_bluetomato Here is an example script from my migration. Note that I did not use MarkupSeo, in my case I had two fields "seoTitle" and "seoDescription". I highly recommend using the migrations module to execute such logic. $pages = $this->wire('pages')->findMany("seoTitle|seoDescription!='',include=all"); foreach ($pages as $page) { if (!$page->hasField('seo')) { continue; } $page->of(false); foreach ($this->wire('languages') as $language) { $this->wire('user')->language = $language; $title = $page->seoTitle->getLanguageValue($language); $desc = $page->seoDescription->getLanguageValue($language); $page->seo->meta->title = $title ?: 'inherit'; $page->seo->meta->description = $desc ?: 'inherit'; } $page->save(); }
    1 point
  47. News Update - 6 March 2019 Hi all. How time flies! It's been a while since I gave you an update on progress. Taxes Most of the current work has focused on Taxes. Although the last mini update talked about the GUI, the main work has gone into taxes. I went back and forth on this one but I think I've finally arrived at something I am satisfied with. Looking at other systems, I liked both the approaches of Shopify and Woocommerce, but especially the former. The approach we'll take will marry the best of both worlds. In a nutshell, taxes will involve/feature the following: You will first need to set up countries that you will be shipping to (this is done when setting up shipping zones). An overview of the shops tax settings. Tax Overrides: Use this feature to override the base tax rates and taxes on shipping per country and/or country state/province. You can create a product category (aka collection) to which a specific tax override will apply. Tax Exemptions: At each product level, you will be able to specify whether a product should be charged tax or not. However, you will also be able to exempt some customers from paying taxes on purchases. Currently, email addresses will be used to identify such customers. Option to choose if taxes should be charged on shipping rates or not. In cases where more than one tax can be applied, choose whether taxes are compounded (e.g. a country + province tax) or one used instead of the other. Specify whether digital products should be charged tax (e.g. EU VAT) or not. Evidence of buyers location for EU VAT. Specify if taxes are calculated based on origin (where you are shipping from/your shop location) or destination (where you are shipping to)[default]. Specify if stated/displayed prices include taxes already or not. Print out tax reports (how much tax you've charged over a given period). Taxes in the United States are a bit tricky to determine. We'll do our best to accommodate the needs of Padloper users in this country. Please note that although Padloper 2 will ship with base rate taxes for most/many territories of the world, including their states/provinces where applicable, and whilst we'll endeavour to regularly update tax rates, the responsibility to ensure that a shop/business is charging and remitting the correct taxes lies solely with the shop owner. Shop owners can use overrides to update their taxes in cases where Padloper 2 base tax rates are not up to date. We will not accept any responsibility for any wrongful tax deductions due to incorrect base rates and/or overrides. GUI i was hoping to have something for you to look at by now but I needed to sort out tax related logic first. I wanted the logic to guide the GUI design and not the other way around. So, you'll have to take a rain check on this one. Files We had a bit of a think on how to handle files (downloadable/digital products, site-wise assets, etc). No final decision has been made but the goal is to be as versatile as possible. Notifications We've started drafting plans on how this will work. More on this later but this will involve email notification to yourself, customers and shop staff regarding their orders. Some notifications will be (semi-) automated, e.g. sending order confirmation, order status change, etc. That's it for now. By next update, I'm hoping to have something for you to look at, however crude :-). Thanks!
    1 point
  48. Here's something to chew on. Start with this tutorial: https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/ Some code to play with. This creates a paginated ProcessWire-rendered HTML table. Create a module as per above tutorial. Use the following code in your Process module's execute() method. You need to create some people pages. In this example, they use the template 'people'. Edit functionality not included. Have a look at Blog module for that, here. For CSV upload (not included), have a look at Matrix module here for uploading CSV file and here for reading CSV file. /** * Display, Add and Edit People. * * Called when the URL is peoples's page URL + "/people/" i.e. URL Segment. * Renders a table with People information. People can be edited via modal. * * @access protected * @return mixed $form rendered form * */ public function ___execute() { $modules = $this->wire('modules'); $input = $this->wire('input')->post; $pages = $this->wire('pages'); // CREATE A NEW FORM $form = $modules->get('InputfieldForm'); $form->attr('id', 'people'); $form->action = './'; $form->method = 'post'; // CREATE AN INPUTFIELD MARKUP: Will hold list of people table $m = $modules->get('InputfieldMarkup'); $m->textFormat = Inputfield::textFormatNone;// make sure ProcessWire renders custom HTML // $m->label = $this->_('Edit'); // $m->description = $this->_('Click on a title to edit the item.'); // CREATE A NEW TABLE: for people $t = $modules->get('MarkupAdminDataTable'); $t->setEncodeEntities(false); $t->setClass('peopleTable'); // set header rows $peopleTableHeaders = array( '<input type="checkbox" class="toggle_all">', $this->_('Title'), $this->_('Name'), $this->_('Surname'), $this->_('Another Column'), $this->_('One More Column'), $this->_('Published'), #$this->_('Date'), ); $t->headerRow($peopleTableHeaders); // grab a limited number of people to show in people dashboard. Limit is hardcoded in this example $people = $pages->find("template=people, include=all, sort=-created, parent!=7, limit=10"); foreach ($people as $p) { if (!count($people)) break;// if no people found, break early // check if person page is published or not $p->is(Page::statusUnpublished) ? $status = '<span class="unpublished">' . $this->_('No') . '</span>' : $status = $this->_('Yes'); // set table rows $peopleTable = array( "<input type='checkbox' name='posts_action[]' value='{$p->id}' class='toggle'>",// disabled sorting on this in .js file "<a href='{$this->wire('config')->urls->admin}page/edit/?id={$p->id}&modal=1' class='editPeople pw-modal pw-modal-medium'>$p->title</a>", $p->title, $p->person_name, $p->person_surname, $p->another_column, $p->one_more_column, $status ); // render the table rows with variables set above $t->row($peopleTable); }// end foreach $people as $p // display a headline indicating quantities. We'll add this to people dashboard $start = $people->getStart()+1; $end = $start + count($people)-1; $total = $people->getTotal(); if($total) $peopleCount = "<h4>" . sprintf(__('People %1$d to %2$d of %3$d'), $start, $end, $total) . "</h4>"; // add a description to people dashboard {postsCount, limitSelect and instruction OR no people found status} $m->description = $total == 0 ? $this->_('No items found.') : $peopleCount . $this->_('Click on a title to edit the item.'); $m->notes = "People table notes"; $currentUrl = $this->wire('page')->url . $this->wire('input')->urlSegmentsStr."/";// get the url segment string. In this case it is "people" $pagination = $people->renderPager(array('baseUrl' => $currentUrl)); $m->attr('value', $pagination . $t->render() . $pagination);// wrap our table with pagination $form->add($m); $post = $this->wire('input')->post; // render the final form return $form->render(); }
    1 point
×
×
  • Create New...