Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/20/2019 in all areas

  1. I hope that you have had a great week! I’ve been working hard on finishing up the LoginRegisterPro module this week and actually have it ready. But I’ve been told I have to get off the computer in 20 minutes, so so I think I’ll wait till Monday to release it. But I do have the new info page (which is kind of like last week's blog post) and new documentation page now online. The documentation page in particular is pretty comprehensive. In last week’s post there was a form to request more info once it’s released, so if you are interested in this module and haven’t filled out that form, please do. That’s how I’ll be sending out the introduction coupon code this time around, for those that want it. There have also been some core updates this week, but it was just a few commits, so not enough to warrant a version bump today. That’s actually a good thing, as no major new issues turning up means one step closer to merging onto the master branch. There will be a new master version before this year is done! Thank you for reading and I hope that you all have a great Christmas and/or holiday week next week!
    13 points
  2. Hi, here is what I used in last project for about 10 000 pages and and it is very simple and basic script. It's read csv file line by line and create pages, but to avoid execution time limits and to get some other options (eg. "pause" option and later "continue", real-time monitoring, etc.) I use very simple Ajax loop. Here is attachment and inside it is some "how-to" txt file. unzip-and-place-content-inside-templates.zip Please note that I use this for ~10 000 pages (in my case, processing time ~1s/page) and for more than that number you can try to do some optimisations and test it. There are few places for that. Teoretically it can works few days, but is it worth? ? Regards.
    6 points
  3. I just released v1.1.2 which has all the same features but removes dependency from MySQL >= 5.7.8 and fixes some minor issues. The module can now be used on any MySQL setup. You can update to or install from scratch the latest master version. If you run into problems, please report here or open an issue on github. Thank you.
    3 points
  4. Great! Btw.. You don't need to set inbuilt ProcessWire columns like 'pages_id in your getDatabaseSchema() :-). ProcessWire will do it automatically. Same with extra, unless you really are adding something extra. Thanks for confirming! ??
    2 points
  5. This won't work, as you you have no warrant, that the admin has set "default" to German (or English). I think the best way (as we discussed above) is, to provide the translated json language files with the module and the site admin has to import those files into the desired language) Edit: @gebeer you beet me by 2 minutes ...
    2 points
  6. I read your first post again. So you want to load the correct country list file based on the current PW language in the admin, right? Well, this is really easy: Setup your languages with the two letter language code as the name, and as the title enter the name of the language in spoken words: Then in your module's init function enter this to get the correct file and store it in an array (example based on umpirsky/country-list): $this->lang = $this->user->language->name; if ($this->lang == "default") $this->lang = "de"; // then you can load the file from your country list into an array $this->laender = require wire()->config->paths->root . "vendor/umpirsky/country-list/data/$lang/country.php"; No there isn't a way. This was filed as an issue before, and I would also like to see this functionality in the future. I am the maintainer of the german language file, and would not recommend to do it this way. Because a language pack should not contain translations for a custom module. Else a maintainer would have to update/merge the files continously if a module author changes anything. The best way would be if PW natively had support for module language files. I think we should talk to @ryan about this, and propose a request in the processwire-request repo.
    2 points
  7. As far as I understand it, you could bundle language translation json files with the module, let's say in a module folder 'translations'. They won't be installed automagically, though. But in the language edit interface, you can add these json files manually to the 'Site Translation files'. Or am I wrong here?
    2 points
  8. Just wanted to follow up on this. In the current master (v1.1.1) I changed the logic loosely following adrian's approach. This is working fine now. Also it removed an issue that occured with my previous approach. I still need the virtual page, though, to instantiate the Pageimages object. But now my virtual page doesn't need a real images field anymore ?. It is working with a virtual Field now. Code is here.
    2 points
  9. May I ask for the reason behind this? Ryan mentions some advantages of InnoDB over MyIsam in this blogpost. The good news for you: next version (v1.1.2) of the module will revert back to not using MySQL native JSON data type so it will be compatible MyIsam.
    2 points
  10. This week we’ll take a look at LoginRegisterPro — a new module that provides an all-in-one, self contained module for providing new user registration, secure logins, profile editing, and more. It does this all in a manner that is reliable, efficient, comprehensive and secure. As we continue preparing the ProcessWire core dev branch to become our new master, I've been trying to stay hands-off on new feature additions there as much as possible (till the new master is out), and instead focusing on finishing up modules I've had in development. Last time I told you about the UserActivity module, and this time we’ll look at LoginRegisterPro, which is another module dealing with users; though significantly larger in scale/scope. LoginRegisterPro is a module I've been working on for more than a year, and finally this month have it ready to share. While I don't have it available for download today I do expect to have a beta release as soon as early next week. Read this week’s post for more details— https://processwire.com/blog/posts/login-register-pro/
    1 point
  11. Now that the major update for my ImagePicker module is out, I wanted to share how I managed to make images from a folder in site/templates/ behave like a Pageimage with full resizing/cropping capabilities. This was probably the biggest challenge in developing the new features. I first thought to create a hidden page in the page tree that will hold all these images. But this would not have been a clean solution. So I took a closer look on how the Pageimage and Pageimages objects are constructed. Finally I decided to use a virtual (or fake) page to hold the images. It required some method overriding of the Page class and the PagefilesManager class to adjust the paths. Normally images for a page can only live in a folder in site/assets/files/pageid. By manipulating the path of Pagefilesmanager I was able to create a custom ImagePickerVirtualpage object and assign the images from the folder to that page. The virtual page is created at runtime and the DB never sees it. It took quite some trial and error to accomplish this. But finally, you can now manipulate these images just like any other Pageimage object (resizing/cropping). The resulting image variations will be stored in the same folder. There is one little stumbling block. I use an existing images field from the site my field is installed on and assign it to a virtual template of my virtual page. This field then holds all the folder images. I figured that every site that will use my module will already have an images field installed. Very rarely this will not be the case. So for the time being I am leaving the logic as it is. If I find people running into problems, I will adjust this. Code can be found here. One more thing that offered some challenge was storing the data as JSON in the DB and have it fully searchable through the API. Luckily I found an old (and abandoned?) module JsonNativeField from @BitPoet that does just that: store values as JSON and make them searchable. So I borrowed the DB schema and most of the getMatchQuery logic from that module. I still have 2 extra columns for pageid and filename in the DB table. These make sure that in the Pagefinder you can use subfields. Kind of redundant info in these columns but I couldn't figure out another way of making the subfield search work in Pagefinder. If you happen to know how to accomplish this, please enlighten me. Main advantage of JSON storage is that my image field can be used with the marcrura's SettingsFactory module. Also storing values of multiple images this way will be easy and will come in handy once I extend my module to support multiple images.
    1 point
  12. Thanks @teppo for your welcome. I'll give it another try after Christmas and report back. Thanks again!
    1 point
  13. OK, I have it: var orderActionStrings = config.orderActionStrings; $('.ResendInvoiceButton').on('click', function(e) { e.preventDefault(); var a_href = $(this).attr('href'); ProcessWire.confirm( orderActionStrings.confirm_resend_invoice, function() { // OK click window.location.href = a_href; } ); }); This will fully replace this var orderActionStrings = config.orderActionStrings; $('.ResendInvoiceButton').on('click', function() { return window.confirm(orderActionStrings.confirm_resend_invoice); }); with a nice vex dialog! @bernhard thank you for your forum thread! I would have never found this feature as it is completely undocumented (except in the sources).
    1 point
  14. Well... did you actually read it? There are useful hints in there, starting at "IIS was not able to access the web.config file for the Web site or application. This can occur if the NTFS permissions are set incorrectly." And there are several suggestions under "Things you can try". Take a look here:
    1 point
  15. // site/ready.php $wire->addHookAfter("Inputfield::render", function($event) { $field = $event->object; if($field->name !== "yourfield") return; $event->return = "<a href='foo/bar'>Your link</a>"; }); You could use one of the Runtime Markup Inputfields or something like the hook above (untested - just an example to get you started).
    1 point
  16. Hi @Gadgetto Sure, it's very easy: ProcessWire.confirm("foo?", function() { ProcessWire.alert("bar yes"); }, function() { ProcessWire.alert("bar no"); });
    1 point
  17. @kongondo all is good! That ___getSelectorInfo() method was exactly what I needed. It is already live on github
    1 point
  18. You might also need something like this in your getMatchQuery() // if normal sql characters, do 'normal' query, else do fulltext search if($this->wire('database')->isOperator($operator)) { return parent::getMatchQuery($query, $table, $subfield, $operator, $value); } else { $ft = new DatabaseQuerySelectFulltext($query); $ft->match($table, $subfield, $operator, $value); return $query; }
    1 point
  19. Try ___getSelectorInfo(). Grep wire folder for full examples. Here's some example code. @see the label index in the code. <?php /** * Get information used for InputfieldSelector interactive selector builder * * This is for Lister purposes. * We want nice labels for our lister selects (i.e. not raw db ones, i.e. 'some_column'). * * @param Field $field The field we are working with. * @param array $data Array of extra data, when/if needed. * @return array * */ public function ___getSelectorInfo(Field $field, array $data = array()) { $info = parent::___getSelectorInfo($field, $data); ## filterable subfields for this field ## // we get rid of the subfield 'data' instead, we'll use 'custom one' => IF APPLICABLE TO YOU! if(isset($info['subfields']['data'])) unset($info['subfields']['data']); // unset misc_data (example column we don't need in filter) if(isset($info['subfields']['misc_data'])) unset($info['subfields']['misc_data']); $subfields = array( // @note: @see getMatchQuery! // text column example 'some_text_column' => array( 'name' => 'some_text_column', 'input' => 'text', 'label' => $this->_('My Text Column'),// NICE LABEL FOR LISTER // @note: comment out those that don't make sense! 'operators' => array('%=', '!%=', '*=', '!*=', '~=', '!~=', '^=', '!^=', '$=', '!$=', '=', '!=', '=""', '!=""'), 'options' => array(), ), // number column example 'some_number_column' => array( 'name' => 'some_number_column', 'input' => 'number', 'label' => $this->_('My Number Column'), // @note: commented out those that don't make sense 'operators' => array('=', '!=', /*'<', '>', '<=', '>=',*/ '=""', '!=""'), 'options' => array(), ), ); $info['subfields'] = array_merge($info['subfields'], $subfields); return $info; } If it doesn't work, I'll need to dig a litter deeper...
    1 point
  20. Yes it should (but test ?). Just remember that in your getDatabaseSchema() for data, you will need to set correct column type (text or varchar, etc) and the correct index type (fulltext most likely if using text).
    1 point
  21. Yes it is, unless something changed that I am not aware of. In __sleepValue() and __wakeupValue() convert it from/to your property and in getMatchQuery() make sure to pass the correct $subfield (as you are currently doing in both respects). What are you currently using data for? pageid? Please show us an example search.
    1 point
  22. Yeah. You can do a lot of fancy stuff in wakeupValue(). You can even create run time values and add them as properties in your $field object, or even fetch data elsewhere and add these as runtime properties, etc.
    1 point
  23. Thank you for the info. That is exactly what I am going to do now. Up to the point where I started developing this module, I was not really familiar with how field values travel through a live cycle. But meanwhile I realized, that the return value of wakeupValue() is what gets passed to the inputfield. I am returning json here already. And now that I decided to kick the JSON data column altogether, the redundancy will be gone ?
    1 point
  24. Thanks for the clarification. I don't know how SettingsFactory works. However, I doubt it accesses your field's database schema. I would imagine it will only be interested in the data you return in ___wakeupValue(). In addition, I don't know how SettingsFactory fetches the data, i.e. automatically or via an API called by the developer. Is it not possible for devs to convert what is returned in FIP to JSON/text for use in SettingsFactory? Alternatively, if you wish to return JSON values, you can do that in ___wakeupValue() but store your respective data sets (pageid and filename) in separate columns without the need for that extra column. It's not a deal breaker in FIP but you really want to avoid data redundancy in your database. Maybe if I understood better how SettingsFactory works I'd be able to give a better-informed response.
    1 point
  25. First of all ISO 3166 is for countries, not languages – there are countries like switzerland, which has 4 official languages. ISO 639 is what we would need. But ProcessWire doesn't care about that. You could be needing Globish, which doesn't have an iso code. So the iso code should always be optional anyways. This difficulty is exactly why I made my PR not rely on an automatic mapping, but simply let users decide which translation to import into which language of the system. Once processwire might add an field for iso codes to the languages template it's an easy addition to detect matching codes and suggest imports to the user automatically.
    1 point
  26. Not "exactly", as I added a slug/url field your proposed solution ? So we are thinking the same, and we should add a request for this, but it is a breaking change to the core. Not sure if Ryan is willing to do this. Or he/we finds a way to be backwards compatible, where the language name is different than the ISO code. The PR that @LostKobrakai provided is a bit different to this behaviour, as it would require users to import the translations by hand. The new solution could load the translations automatically, as the language code is predefined.
    1 point
  27. This is already integrated. Each country (most countries!) has its own locale data (currency symbol, tax rate, provincial/territorial taxes if applicable, tax names, decimal symbol, etc). Tax rates can be overridden per country (and per territory if applicable). This is a frontend issue which you will need to integrate yourself using ProcessWire $language API and your method of detecting customers location (taking into account the various pros and cons of each). This is about shipping zones. It is already built in but you will have to set up the zones yourself including: The shipping countries (and territories if applicable) Shipping rates in that zone, whether they are flat- or price- or quantity- or weight-based Whether you are using shipping classes (e.g. light goods, fragile products, hazardous, bulky, etc) As well as shipping methods (e.g. normal, express, next day, Post Office, etc). Specifying a maximum shipping fee (if you wish) as well as shipping handling fee (optional) Etc The above allow a lot of control straight out of the box. This is about a 3rd-party software. You will have to do the integration yourself using Padloper 2 API (for inventory). Probably not practical in your case, but please note that in Padloper 2 you can manually create an order (or using the API).
    1 point
  28. Problem is, that you cannot predict which names people use for languages. So you cannot rely on a specific standard here. If someone installs your module who has named the German language 'german' and not 'de_DE', the module author has no way to reliably map translation files to country names.
    1 point
  29. That is correct. Additionally you can send the language files to the maintainers of language packs. I think that editors don‘t get the core backend untranslated, but need a single module translated. (What also can be done with one additional step, if the language files are distributed together with the module) For me it doesn‘t look that bad as described by @dragan.
    1 point
  30. Yes, I have a 'double storage' at the moment. Because I had not finally decided how to handle this. So atm there is redundant data. Main reason for adding that JSON column was so I can support SettingsFactory which only can store text values. Also, after switching to JSON storage, I left pageid and filename columns so that in the Pagefinder you can choose these as subfields. Do you know a better way to handle this? Anyways, I will be going to set data column as a text in the next version to avoid the MySQL >= 5.7.8 requirement and amend the query logic to query pageid and filename columns instead of doing the JSON_SEARCH() on the data column.
    1 point
  31. That's "where I come from" as well :-) That has been bothering me for quite some time too - in the context of PW Pro modules that were going to be used in a ML setup. I had to translate every single string of Lister Pro, Pro Fields.... modules etc. myself, so that the client's backend-admins / authors had the interface available in their own language as well. This - to me - is a massive oversight by Ryan. You buy a Pro module, and probably every other aspect in the work-flow is ML-capable, but the actual backend GUI is not.
    1 point
  32. https://dockyard.com/blog/2019/12/19/lessons-learned-10-years-of-running-a-software-consultancy
    1 point
  33. Html the way to go. I think focusing on developers instead of newbies would be better. What about a component kit example say: Navigation - 10 layouts Hero pages - 10 layouts Product pages - 10 layouts Slider content - 10 layouts News pages - 10 layouts Data - 10 layouts etc So you could pick and choose elements to create final theme. If theres any issues that developers face regarding theming and designing applications would be great to know. Thanks
    1 point
  34. @dragan & @wbmnfktr, your suggested method (the admin needs to map the languages) currently seems to be the way to do this. I just don't think it's very elegant. After all, I'll probably implement the country list as a standard array with PW language methods. This is the way how PW handles it. I could try to generate the PHP language files with their language methods programmatically.
    1 point
  35. Gadgetto thanks for your solution! ? Guys, I found what I was looking for: https://processwire.com/talk/topic/9007-utility-to-help-generate-module-install-function/ it just uses normal processwire json export strings for fields and templates and seems for me to be the simpliest solution... I used it once somewhere in a module, it worked, but I forget where I had it.. ?
    1 point
  36. It is done. I have merged this module with the ImagePicker module. Now it includes almost all requested features. It is published as FieldtypeImagepicker on github. I will update the ImagePicker thread shortly and continue discussion there. Hope to see you!
    1 point
  37. This week we’ll take a quick break from core updates and have a look at a new module called UserActivity, just added to the ProcessWire ProDevTools package— https://processwire.com/blog/posts/user-activity-module/
    1 point
  38. Yep, it must be installed. It is called Page Path History module, found among the core ones.
    1 point
  39. Hmm... When I try this with templates I get the error "You must save Fieldgroup 'X' before adding to Template 'X'" It seems like that would be the job of the setImportData() function to make sure that happens? Edit: Got it. Here's the template builder: protected function buildTemplatesFromJson($json) { $data = is_array($json) ? $json : wireDecodeJSON($json); // Loop through each template in the JSON foreach($data as $name => $templateData) { unset($templateData['id']); // Get rid of the ID so it doesn't conflict with the new installation $template = $this->templates->get($name); // If the template exists, grab it // Create the template if it doesn't already exist if(!$template) { $template = new Template(); $template->name = $name; } $template->setImportData($templateData); // Import the data for the field $fieldgroup = $template->fieldgroup; $fieldgroup->save(); $fieldgroup->saveContext(); $template->save(); if(!$template->fieldgroup_id) { $template->setFieldgroup($fieldgroup); $template->save(); } } }
    1 point
  40. Okay, so after playing around with this and looking at Ryan's code in ProcessFieldExportImport I was able to put together a simplified function to create fields from a JSON export. This only creates a field if it doesn't already exist, and you can do it one at a time or send in multiple fields at once. protected function buildFieldsFromJson($json) { $data = is_array($json) ? $json : wireDecodeJSON($json); // Loop through each field in the JSON foreach($data as $name => $fieldData) { unset($fieldData['id']); // Get rid of the ID so it doesn't conflict with the new installation // Create the field only if it doesn't already exist if(!$this->fields->get($name)) { $field = new Field(); $field->name = $name; $field->setImportData($fieldData); // Import the data for the field $field->save(); } } } Calling it from within my module's install() function: $this->buildFieldsFromJson('PASTE_JSON_EXPORT_HERE'); Hope that helps someone else. Now onto the templates...
    1 point
×
×
  • Create New...