Leaderboard
Popular Content
Showing content with the highest reputation on 12/23/2020 in all areas
-
I'm not sure if this requirement is common enough it that will be considered for the core, but you can easily extend those Fieldtypes by yourself. These are untested, but they should work. It should even be possible to switch an existing FieldtypeText or FieldtypeTextarea to a non-indexed type.: FieldtypeTextNoindex <?php namespace ProcessWire; /** * ProcessWire Text Fieldtype without Index * * Fieldtype equivalent to FieldtypeText but * without creating an index on its text content * to preserve storage. * * Only use this Fieldtype if you will never search * through the contents of the field. * */ class FieldtypeTextNoindex extends FieldtypeText { public static function getModuleInfo() { return array( 'title' => 'Text Noindex', 'version' => "0.0.1", 'summary' => 'Field that stores a single line of text, not indexed' ); } /** * Return the database schema in specified format * * @param Field $field * @return array * */ public function getDatabaseSchema(Field $field) { $schema = parent::getDatabaseSchema($field); unset($schema['keys']['data_exact']); unset($schema['keys']['data']); return $schema; } } FieldtypeTextareaNoindex <?php namespace ProcessWire; /** * ProcessWire Textarea Fieldtype without Index * * Stores a large block of multi-line text like * FieldtypeTextarea but without an index on its * text content to save storage space. * * Only use this Fieldtype if you will never search * through the contents of the field. * */ class FieldtypeTextareaNoindex extends FieldtypeTextarea { public static function getModuleInfo() { return array( 'title' => 'Textarea Noindex', 'version' => "0.0.1", 'summary' => 'Filed that stores multiple lines of text, not indexed', 'permanent' => true, ); } /** * Get database schema used by the Field * * @param Field $field * @return array * */ public function getDatabaseSchema(Field $field) { $schema = parent::getDatabaseSchema($field); unset($schema['keys']['data_exact']); unset($schema['keys']['data']); return $schema; } }3 points
-
Thanks everyone. I have also found some brilliant articles at Hongkiat including this one on moving items in a CSS grid.3 points
-
ok, well at the risk of hijacking this thread and turning it my dev process (hey, it is dev-talk anyway) ... I've created an app on Cloudways which is a skeleton project with the settings I nearly always end up using on a project. These are (more or less): Modules: AIOM TfaTopt Tracy Debugger TextformatterVideoEmbed TextformatterVideoEmbedOptions TextformatterTableWrapper there are more that probably could go on that list but I think pretty much every site I've done has those. Config tweaks: adding Markup Regions and webp, and disabling session fingerprinting when the site's in debug cos otherwise I keep getting logged out when testing in responsive design mode ... Templates: Basic site layout and then various things like pulling in meta tags / CSP etc, generating a nonce for inline scripts, password protecting the site whilst it's in debug mode. CSS gets pulled in either via AIOM or directly if the site is in debug. For CSS I generally have half a dozen files (definitions / grid / nav / typography and so on) that I've built up over the years but are mostly based on bits of other libraries eg we pretty much have the Bootstrap grid then there's adding a humans.txt file and tweaks to .htaccess (things like Strict-Transport-Security and ahem, X-Clacks-Overhead ). And there's a few application settings like disabling Varnish which never seems to work well for me on dynamic sites. What else ... oh yeah, a .vscode folder in the root of the project set to 400 so I don't accidently upload project settings (yeah that's happened). Now I can just clone that skeleton app in Cloudways and I'm off to a great start for a new project. Looks like cron jobs aren't cloned which is a shame because I have a cron job I normally use to dump database backups (which are easier to roll back than the default Cloudways backups) but that's easy enough to add. And it would be nice to be able to prompt me to change the PW admin user login as well when I log into the cloned site so I don't end up resusing passwords. I'll have a think about that. I'm sure this will save me time going forward - best get on with the sites I was supposed to be building today though....2 points
-
Ok, it seems that I have found the root cause. In wire/core/Sanitizer.php - Sanitize selector value (version 2, 3.0.156+) function has a reduction: line 2295: $reductions = array('..' => '.', './' => ' ', ' ' => ' '); This causes the problem in case someone else is wondering the same thing.2 points
-
Thank you for sharing your thoughts, I definitely do not enjoy working with those open source ecommerce systems, development is never a straight line. I will try your approach next time I have this client conversation. The funny thing is that Snipcart's fee is almost fully covered by the difference in Stripe fees between the US and the EU and it's still more competitive than Shopify.2 points
-
I have a site with about 16K pages, with most of these (15K + ) being templates with just two text fields (including page title), along with several page reference fields, and a couple of numeric fields and all the tables take up just over 20MB of storage, however there is a huge full text index file of over 2.1GB that seems to be totally out of proportion to the size of the database. Does anyone know whether this is normal behaviour with Processwire? From the reading I've done, it seems a full text index of similar size to the table it indexes is not unexpected, but 100x the size of all the tables in the database seems excessive. If this isn't normal, what's the best way to fix this? Edit: It turns out the huge index was related to logging of imports to a text field by this module: I'll post in that thread regarding the issue since it's module related.2 points
-
I've updated Combo to use @Robin S strategy for moving the subfields around the page editor and posted it in the ProFields download thread as v2. The definition is available for any Combo subfield and it's very simple, but I figure it's something at least to start with.... it's working and ready to use. It does use a datalist-based autocomplete, so you don't necessarily have to remember all your field names. Thanks Robin S. for the idea on how to make it work, it seems to be a clean and reliable way to do it.2 points
-
@Adam Thank you! It works very well now. I also tried to include it on a front end login page (which does not use the Login/Register (pro) module). With the example in the Tfa class the authorization form was never called and I figured it was because the tfa token changed because tfa's success method was called without tfa being started yet. So the token was reset and hence mismatched with the token in the get variable. Using a new session variable did the trick. I thought I'd share this if anyone also comes across this. $tfa = new Tfa(); $tfaStarted = $session->get('tfa_started'); if ($tfaStarted && $tfa->success()) { //redirect to some page if logged in $session->redirect('/some/page'); } else if ($tfa->active()) { //only set this variable if $tfa->active() is true. That also means the auth form is rendered. $session->set('tfa_started', true); //echo the form somewhere in your HTML $tfaRender = $tfa->render(); } else if ($input->post('login_request')) { //get input name and password (also CSRF token...) $inputName = $input->post('user_name'); $inputPassword = $input->post('user_password'); $tfa->start($inputName, $inputPassword); $session->remove('tfa_started'); /* do regular login stuff here if user has no 2FA set up */ } else { // render login form if ($session->get('tfa_started')) { //remove session variable and reload page (otherwise $tfa->success() would be called) $session->remove('tfa_started'); $session->redirect($page->url); } } /* don't forget to include scripts in your HTML markup <script src="<?= $config->urls->siteModules ?>TfaU2F/u2f-api/u2f-api-polyfill.js"></script> <script src="<?= $config->urls->siteModules ?>TfaU2F/TfaU2F.js"></script> */1 point
-
@Gadgetto or anyone else who uses Snipcart to build stores for their clients: How do you justify the extra cost (minimum monthly fee / transaction fee) to clients over free solutions such as Padloper? I'd love to use Snipcart with your integration but given the choice clients go with a free to run system. Sorry this is not a technical question but thought you regularly work with Snipcart if you took the time and effort to develop such a deep integration.1 point
-
This is not yet supported by SnipWire directly. I first need to create a special field type which offers alternate price list creation. This feature is already on my todo list!1 point
-
Based on the Modules class it looks like module versions are checked by Modules::checkModuleVersion(), which gets called when individual modules are initialized (Modules::initModule()). From here on I'm largely guessing, but what I'd probably try first would be iterating over all modules (assuming that you want this to occur for all of them) and then calling something along the lines of... if ($modules->isInstalled($module_name_or_class) { $modules->get($module_name_or_class); } ... for each of them — first check is just to make sure you don't accidentally install all modules, while get should trigger upgrade check (if I'm correct, that is) ? Sounds a little hacky, not sure if it'll work 100% or if there's a more straightforward way. I couldn't spot one, though.1 point
-
I recently did an import of about 15K records with these modules, and they worked well, however there was one undesirable side effect of storing the log to a standard Processwire text_area field, log_messages. Processwire creates a full text index on text_area and text field types. I had a few issues with field mappings and defining unique identifiers the first couple of times I ran the import, so just used Tracy Debugger to delete the pages, fix the import definition, and run the import again. Unfortunately, over my efforts, the full text index on the field log_messages grew to over 2GB in size, even though the imported CSV file itself was only about 1MB. It took me a bit to figure out why the database had suddenly grown from a few MB to several GB, and once I located the problem, I ran Optimise Table in mySQLAdmin, which cleaned things up and got things back down to a normal size. I suspect in this case, the log_messages field probably doesn't need to have a full text index on it, although I guess if someone has a large number of import pages, maybe there is a case for them to be searchable? If there isn't a need for the log_messages field to be searchable, then perhaps a custom text fieldtype without a full text index might make both the import run more quickly if the field is repeatedly updated during import, and also avoid the issue of creating an enormous index file. I've made a post to the Wishlist and roadmap thread, suggesting an option for textarea fields to have indexing disabled if not required, as this would resolve the issue.1 point
-
I’ve just released the first version of the ProFields Combo field and it’s now available for download in the ProFields support board download thread! Rather than writing a long post today, I’ve instead focused on writing the Combo field documentation. The documentation page includes a lot that you may already know from previous posts, but it also includes a lot of new details that haven’t yet been posted. Please consider this version to be a development/beta version. It’s the first release and hasn’t had a lot of testing yet, so consider it not yet ready for full production use. Though if you get a chance to test it out, please let me know how it works for you. I appreciate any feedback you have. A couple things I haven’t yet tested thoroughly enough yet are exporting/importing of Combo fields or pages using combo fields. I also haven’t done enough testing in FormBuilder yet. So I’d recommend avoiding use of PW’s field or page export/import functions with this, or using in FormBuilder, at least for a few days. By next week I will have tested those things and made any necessary updates. Thanks for reading and have a great weekend!1 point
-
@Robin S No doubt, that would be nice. But as far as the core goes, that's a pretty major project and involves creating a new interface method for all Fieldtype modules. It could be months, and I'm not sure we'll ever get into that or not, or whether 3rd party, etc. Whereas, this was something simple that could be added today, right now, that will at least make the option available. If it sees a lot of use, I'm sure we'll keep expanding the options. But as it is right now, Combo is the only field that can do this (thanks to your contribution), so I think it probably makes sense that it's also the place where you specify it, at least for the moment. It's not perfect, but very often pursuing perfection means either never starting, or never finishing. ? @adrian Actually the list position is still relevant, it just becomes relative to any other fields that have been moved to the same field. Or if the field being moved-to is present in one template and not another where the Combo field is used, then the list position is also still relevant when it displays in the Combo field. Let's say you specified the same "body" field for all of the subfields in the Combo (to insert after). It would move all those fields after the "body" field in the page editor, and they would retain the drag/drop order you have put them in. The end result would look the same as the Combo field, but without the wrapper/fieldset. I had to play around a bit to get this working, but it is in the version I posted, so wanted to mention that the list position still matters, especially if moving multiple subfields to the same location.1 point
-
A quick proof-of-concept using the API only... Before (Combo subfields grouped together inside fieldset): After (Combo subfields interspersed with other fields): Hooks: // Reposition Combo subfield inputfields in Page Edit $wire->addHookAfter('ProcessPageEdit::buildFormContent', function(HookEvent $event) { /** @var InputfieldWrapper $wrapper */ $wrapper = $event->return; // Imagine this is sort order data coming from some config field $insert_after = [ 'test_combo_colours' => 'image', 'test_combo_description' => 'file', 'test_combo_decimal' => 'test_repeater', ]; // Get the Combo subfield inputfields $combo = $wrapper->getChildByName('test_combo'); $combo_inputs = $combo->getInputfields(); // Reposition them foreach($insert_after as $combo_subfield_name => $normal_field_name) { $combo_subfield = $combo_inputs->getChildByName($combo_subfield_name); $normal_field = $wrapper->getChildByName($normal_field_name); $wrapper->insertAfter($combo_subfield, $normal_field); } // Cannot just remove the Combo inputfield or else subfield value changes don't get processed // So instead a separate hook is used to replace the rendered output of the Combo inputfield // $wrapper->remove($combo); $event->return = $wrapper; }); // Don't render anything for the Combo inputfield $wire->addHookBefore('InputfieldCombo::render', function(HookEvent $event) { /** @var InputfieldCombo $inputfield */ $inputfield = $event->object; $field = $inputfield->hasField; if($field->name === 'test_combo') { $inputfield->wrapAttr('style', 'display:none'); $event->replace = true; }; });1 point
-
You need to create enough rows and columns, and span your contents, I believe. See Jen Simmons here:1 point
-
Kevin Powell has a good tutorial using grid columns and rows to overlap content.1 point
-
Greetings! Webflow has an super nice tutorial on implementing this using their app, BUT it's totally fine to just learn from it and to it by hand, so if you are more of a visual learner, like me, you'll enjoy it:1 point
-
Important update to the module with a new release. Recommended that all users upgrade to the latest version The module has been updated with critical fixes and feature requests fulfilled. The module has been updated to fix an issue with lengthy content that would result in failure, mostly important for CKEditor fields that include markup in the content. This was due to the admin AJAX call to the module using a GET request where a POST request should have been used to prevent running into URL length issues. Translation was pulling from the wrong location in CKEditors so it was translating the last saved content, not the latest changes made in the field before page save. Use of Fluency is now permission based as requested. After upgrading all roles who should have access must have the fluency-translate permission added The configuration screen now has a new setting for the Preserve Formatting feature which addresses the issue reported in this thread where short strings or phrases were being returned with additional/missing punctuation. (internally this uses the preserve_formatting DeepL API parameter). It is recommended that this be enabled unless you have a specific reason not to use it. Public methods have been added to the Fluency module so that translation, usage stats, and available languages can be pulled from calling the Fluency module or by using the DeepL class directly. README has been updated with documentation for usage. A new parameter has been added to both the Fluency and DeepL translate methods that allow you to pass in any DeepL API key/values with your request. If you are currently calling either the module or DeepL class directly, please read the documentation as the parameters have changed. Return values from the Fluency module now match the return values from the DeepL module for consistency. This includes passing DeepL's HTTP response for use in programmatic conditions. The module has been moved from Gitlab to Github to adhere to ProcessWire's module directory requirements for future listing. As usual, more to follow! Latest: https://github.com/SkyLundy/Fluency-Translation/archive/main.zip Paging @adrian & @xportde & @bartelsmedia as you've been Fluency's alpha testers extraordinaire.1 point
-
@netcarver @androbey Just pushed out 1.0.2 on Github. was a very simple fix actually but took a while for me to figure it out doh might take a while to show the new version on the modules site but will try and update that now too1 point
-
Thanks for this great new module @ryan! The Combo module seems in some ways like an enhanced ProFields Textareas: both modules provide multiple inputfields that look just like real separate fields in Page Edit but are contained in a fieldset and are actually just one field behind the scenes. As you've said, this is great for efficiency because it reduces the total number of fields needed for a project. In some big sites I've worked on the ProFields Textareas module has been fantastic because it's reduced the number of fields I need by 50% or more. The new Combo field looks like it will be even better than Textareas so I'm excited to start using it. But there is something that holds Textareas and Combo back from being even more useful, and that is the fact that all the subfields have to be rendered together inside a fieldset. In my experience there are many situations when you have fields in template that technically could be catered to by Textareas (and now Combo) but the problem is the layout in Page Edit: 1. The subfields of the Textareas/Combo are not sufficiently related to each other that they should be grouped together inside a labelled fieldset. What I mean is that as a developer you identify fields whose technical requirements make them a good fit for Textareas/Combo, but the fields don't conceptually belong in the same group in the mind of the client/administrator, so you don't want them all grouped together under one parent fieldset label. 2. You have some other separate fields (e.g. Repeater, ProFields Table) that you want to intersperse between the Textareas/Combo subfields. The consequence of these two problems is that it either isn't practical to use Textareas/Combo in some situations where it has the potential to avoid a lot of extra fields, or you end up creating many more separate Textarea/Combo fields than are necessary or desirable from a technical point of view. You might remember that I raised this in the Textareas forum, and ended up making a hacky module that rearranged the Textareas subfield inputfields in Page Edit so I could get around the two issues described above. But what I'm dreaming of is having a core or official ProFields solution to this... What I'm imagining is an enhanced version of the core template editor. If a field is added to a template and the fieldtype reports that it renders multiple subfield inputfields (Textareas and Combo are the only fieldtypes I can think of that do this, but perhaps more fieldtypes will fit the bill in the future) then those subfields become individually sortable in the template editor. So it would be possible to make a layout in Page Edit that went something like... title combo.text repeater combo.textarea table combo.integer etc Here's a screenshot of the interface of my hacky module to show the general idea - although this is actually separate from the template editor and is therefore not nearly as good as it could be. (And before anyone asks, this module is way too buggy and hacky for me to release publicly, hence my request for a solution from Ryan). I know this wouldn't be a simple thing to implement but I think it would make ProFields Combo and ProFields Textareas hugely more useful. Thanks for considering!1 point
-
Hi @Mats thank you for this module! I noticed an issue when trying to crop images which where downloaded via this module on saving. The error said that the image could not be found. I assume this has to do with the page file name, which has a "." in its name, which seems to be a problem. I replaced the renaming with following line, which solves this problem for me. Maybe it's helpful for someone else coming accross this. $pagefile->rename(str_replace('.', '-', $pagefile) . ".jpg");1 point
-
I know this is old, but just a follow up to mention that Tracy Debugger has a few options for achieving similar functionality. Files Editor panel lets you test changes without affecting what other users see. When ready you can push the changes live. Template Path panel lets you choose from a variety of templates with -dev, -test etc suffixes. The User Bar has a "Page Versions" component that lets authorized users choose from alternate templates (this is basically a non-superuser version of the Template Path panel. User Dev Template Options - this lets you set users with certain roles to automatically see the page with a different version of the template file. Anyway, thought some of these might be useful to others who come across this topic.1 point