Leaderboard
Popular Content
Showing content with the highest reputation on 03/31/2021 in all areas
-
100% recommendation for tabulator! I'm using it all over now in several projects and I'm finally very happy. Having tried datatables, aggrid and tabulator I can say that I've tried a lot of them and tabulator is IMHO the best overall - and it's MIT ? The custom filter you are talking about should be easy. If you need help just give me a shout ?4 points
-
You can think of it like this: Fieldtype = responsible for storing/sanitizing data Inputfield = responsible for UI/markup That's why it is very simple to create an inputfield. A very basic inputfield could just output "hello world" without any connection to the DB or other business logic. It's not exciting to avoid the DB, but if its not necessary because you use the Inputfield just for presentation then you can simply save time/effort that is not needed ? On the other hand using Inputfields instead of plain HTML has the benefit that you get a UI component that every PW user is familiar with and that you can control like any other Inputfield (setting columnWidth, toggling, label, icon, ...). See https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/#adding-your-first-field-inputfieldmarkup The name INPUTfield can be a little confusing at the beginning, but after time it made a lot of sense for me and I could not think of a better wording now.3 points
-
Your link to my example is wrong - I guess you mean this one ? The main advantage of using constants is not about being able to change names (as that happens almost never) but to get better structure into your code and also get additional information that you do not get from regular strings or object properties. And I'm using it a lot with array syntax but you are absolutely not limited to that! And you cal of yourse always use class constants in strings: $pages->find("template=".Foo::tpl); But here are some very simple examples why I'm using that approach in the first place. Imagine you wrote code 1 year ago and look at it to fix a bug or add a feature. Compare those two: // example migration $rockmigrations->createField("type", ['type' => 'text', 'collapsed' => 2]); // example find $pages->find("template=animal,type=1|2,category=3|4|5"); // example migration $rockmigrations->createField(Animal::field_type, [ 'type' => 'text', 'collapsed' => Inputfield::collapsedBlank, ]); // example find $pages->find([ "template" => Animal::tpl, Animal::field_type => [Animal::type_cat, Animal::type_dog], Animal::field_category => [ Category::small, Category::medium, Category::large, ], ]); Or with better syntax highlighting: Imagine you had to answer these questions: where (to which pages or logical parts of your app) does the "type" field belong to? which animal-categories am I listing with my page find operation? what is the collapsed state of my Inputfield? Which of the two code bases above would you want to manage? ?2 points
-
A bit of a wild guess, but maybe there's something messed up in the FileCompiler cache (site/assets/cache/FileCompiler). Cleaning that out and checking that the web server user is the owner might be worth a shot.2 points
-
Thanks to @bernhard introducing me to Tabulator, I've used it in several projects too - both admin and frontend side. It's powerful & fast. Once you get your PW PageArray converted to json, it's just a matter of defining your columns, filters & CSS2 points
-
To reduce maintenance effort, it seems to me to be important that there is a clear and manageable interface between names in the PW database and those in your PHP code. But what is the best way of achieving this? Firstly, I think the use of custom Page classes helps enormously, but then what? Two PW gurus to whom I usually look for inspiration seem to have different approaches. @Robin S appears to favour defining properties above the class, as is exemplified in his AutoTemplateStubs module. Alternatively, @bernhard uses constants to define fields (see here for example). Both work but have pros and cons. The first approach seems more straightforward and fits naturally into the normal PHP object->property syntax and PW selector syntax, but if you change a fieldname in the database, you have to get your IDE to refactor it in the code (PhpStorm seems to handle this fine - refactor the @property definition and all the accessed properties get changed). The second approach limits your syntax to an array-style, but means you just change the constant value if the field name changes - no refactoring required. Any other views on this, or better ideas?1 point
-
1 point
-
I don't think you're being dim - you're just running up against a necessary limitation of what the AutoTemplateStubs module does. The module is only ever going to operate on files in the AutoTemplateStubs directory that it has created itself. As a matter of safety it's not going to get into the business of modifying/overwriting/deleting files that you have created, such as your custom Page class files. When custom Page classes are not in use AutoTemplateStubs creates stubs for class names like "tpl_basic_page", which don't exist anywhere else in the codebase. They're not "real" classes that do anything - they're just a way to tell the IDE about overloaded properties when you use a PHPDoc comment to (falsely) state that $page is an instance of class tpl_basic_page. But if you are using custom Page classes then two things apply: 1. There are necessarily going to be two different class files using the same class name - the "real" class file that you create, and the "fake" class file that AutoTemplateStubs creates. Your IDE will probably warn you somewhere that there are multiple definitions for the same class name. 2. Your IDE "knows" that $this is your custom Page class, and it's likely to "prefer" what it knows about $this from the custom Page class file over anything that is contained in the AutoTemplateStubs stub file. You can manually copy over the PHPDoc comments from the AutoTemplateStubs stub file to your custom Page class file if you find that's useful, but nothing is going to be kept in sync so you won't be getting the "auto" part of AutoTemplateStubs.1 point
-
Don't overthink it. You're gonna need a way to reference a specific field anyway. Hiding the name away behind a constant, config or whatever isn't going to change that. If you're worried about changing field names, you should instead invest the time to find better names for your fields. Why would your field names change? Probably because the data they hold or the thing they represent have changed - both of those cases will require adjustments in the templates anyway. I've never understood the benefit of "hiding" a property or method name behind a constant. I mean, what are you gonna do if the field name behind it changes? Let's say I have the field field_for_thing_a and use a constant FIELD_NAME_THING_A to hide the dirty, dirty field name string behind a nice, verbose constant. Now I need to rename the field to field_for_different_thing_b. Am I just gonna leave the constant in place? So FIELD_NAME_THING_A now references something completely different? No, I'm gonna rename it, in which case I could just find+replace the name of the thing itself and will introduce a BC break anyway. But if the field needs to change, it's not backwards compatible anyway. The only backwards compatibility I'm maintaining at this point is unreadable cargo cult code ? Of course, there are exceptions. Depends on what you're building. If you're talking about a module which might need to access a user-defined field, by all means, store the field name in a variable (it's gonna be pulled from the database anyway if it's configured in the module settings). Maybe I'm way off base here. What problem are you actually trying to solve? Maintainability is a spectrum and doesn't exist in a vacuum. What maintenance burden do you want to avoid?1 point
-
I've addressed that here. Hopefully I'll get to release some code shortly ?1 point
-
I ended up using Guzzle to do, for example, the following: // Shopify init function shopifyQL($query) { $shopifyHost = "xxxxx.myshopify.com"; $shopifyPassword = "xxxxx"; $graphqlEndpoint = "https://$shopifyHost/admin/api/2021-01/graphql.json"; $client = new \GuzzleHttp\Client(); $response = $client->request('POST', $graphqlEndpoint, [ 'headers' => [ 'Content-Type' => 'application/json', 'X-Shopify-Access-Token' => $shopifyPassword, 'X-Shopify-Api-Features' => 'include-presentment-prices' ], 'json' => [ 'query' => $query ] ]); $json = $response->getBody()->getContents(); $body = json_decode($json, true); $data = $body['data']; return $data; } // Get Shopify shop defaults (useful for currency checks) wire()->addHookMethod('Page::shopifyShop', function($event) { $page = $event->object; $query = <<<GQL query { shop { name primaryDomain { url host } } } GQL; // Get cache only if it's less than or equal to 1 month $result = wire('cache')->get('shopifyShop', WireCache::expireMonthly); if (!$result) { $result = shopifyQL($query); wire('cache')->save('shopifyShop', $result, WireCache::expireMonthly); } $event->return = $result; });1 point
-
yes, just set visible=false http://tabulator.info/docs/4.9/columns#visibility1 point
-
Maybe you aren't allowed to write changes to site/config.php and need to change read/write settings first. Double check the changes were submitted to the server and not to your local file. Either log in via SSH or maybe even via WebFTP or something. Oh... and check if there is a second $config->debug in your site/config.php. If so... delete it.1 point
-
1 point
-
Thank you @BitPoet this makes totally sense, I should have thought about that. That solved my issue and I am super happy.1 point
-
Just checking: you know for certain that you have published, unhidden pages that use template "my-template" as descendants of $page (i.e. you can see them in the page tree) but they are not returned with either: $results = $page->find("template=my-template"); or $results = $pages->find("has_parent=$page, template=my-template"); (both of these are effectively the same thing) If that's the case it's possible that something has gotten messed up in the pages_parents database table. In PW 3.0.156 or newer you can rebuild the pages_parents table by executing the following in the Tracy console or in a template file: $pages->parents()->rebuildAll(); See method PagesParents::rebuildAll()1 point
-
But we can at least see that it's an InputfieldFormBuilderFile object. Since FormBuilder Inputfields inherit (I took a peek into the code) from the regular Inputfield class, you can refine your debug output to only show its value attribute (you're already reading $font->attr('value') - it's the way to go with all form fields). I'm pretty sure it's going to be some kind of array. wire('log')->save('form-builder-debug', print_r($image->attr('value'), true));1 point
-
This notice can happen if you use a page reference field in your template which has a wrong defined (i.e. deleted) parent page dependency. In my case I had a blog-post template which contained a page reference field to category pages. Additionally I had a parent page defined containing the categories. The error occured when I deleted this parent page.1 point
-
I think $image is likely an array of file paths. What I like to do in such cases is to dump the variable in question to a PW log. wire('log')->save('form-builder-debug', print_r($image, true)); This should give you a clue when you look into Setup -> Logs -> form-builder-debug.1 point
-
You need to use wire('pages')->findOne() to retrieve your fontPage, find() returns a PageArray. Before adding the image, set $fontPage->of(false). Also, you have single quotes around $image.1 point
-
I've realized that I've been jumping back and forth between the PW API docs and the source code for site modules far too much. The idea to hold all necessary documentation locally in one place has occurred to me before, but getting PHPDocumentor et al set up and running reliably (and producing readable output) as always been too much of a hassle. Today I was asked how I find the right hooks and their arguments, and that inspired me to finally get my backside down on the chair and whip something up, namely the Module Api Doc Viewer ProcessModuleApiDoc It lets you browse the inline documentation and public (optionally also protected) class/method/property information for all modules, core classes and template files in the ProcessWire instance. The documentation is generated on the fly, so you don't have to remember to update your docs whenever you update a module. The module is quite fresh, so expect some bugs there. Behind the scenes it uses PHP-Parser together with a custom class that extracts the information I needed, and the core TextformatterMarkdownExtra module for rendering the description part in the phpdoc style comments. This is not a replacement / competitor to the API Viewer included in the commercial ProDevTools package. There is quite some information included in the inline documentation that my module can't (and won't) parse, but which makes up parts of the official ProcessWire API docs. This, instead, is a kind of Swiss army knife to view PHPDoc style information and get a quick class or function reference. If you feel daring and want to give it a spin, or if you just want to read a bit more, visit the module's GitHub repository. This is the overview page under "Setup" -> "Module API Docs": And this is what the documentation for an individual class looks like: The core module documentation can of course be found online, but it didn't make sense not to include them. Let me know what you think!1 point
-
Memo to myself and mybe to safe someone else from losing hours trying to understand why a multi-language Inputfield does not render() as expected... Learnings: 1) Inputfield::render() is only hookable for single-language Inputfields! When PW renders a multi-language Inputfield the LanguageSupport module adds a hook that fires after the original Inputfield::render(). This hook calls the render() method for each language and to avoid circular references it does that directly on $inputfield->___render() and not $inputfield->render(): https://github.com/processwire/processwire/blob/51629cdd5f381d3881133baf83e1bd2d9306f867/wire/modules/LanguageSupport/LanguageSupport.module#L445-L453 2) When building a custom Inputfield that supports a multi-language setup it is critical that its render() method is defined with 3 underscores! Otherwise the LanguageSupport hook that adds the markup for the other languages' fields would not fire.1 point
-
Since some others and me have been run into problems with FieldtypeFloat. I want to start a discussion with the purpose to get a consistent FieldtypeFloat and/or to create a new Fieldtype maybe called FieldtypeDecimal to store exact values maybe for currencies. First I will assume some known problems. precision Values of Type Float are stored in most of the Mysql Installations with a precision of 6 by default. PW FieldtypeFloat uses Type float() in the Mysql Database This could cause some problems. For easy understanding look at this table. +---------------+----------------+--------------------------------------------------+ | input | float() | decimal(10,2) | +---------------+----------------+--------------------------------------------------+ | 1234.56 | 1234.56 | 1234.56 | +---------------+----------------+--------------------------------------------------+ | 123456.78 | 123457 | 123456.78 | +---------------+----------------+--------------------------------------------------+ | 12345678 | 12345600 | 12345678.00 | +---------------+----------------+--------------------------------------------------+ | 1.23456789 | 1.23457 | 1.23 | +---------------+----------------+--------------------------------------------------+ | 12345678912345| 12345600000000 | ERROR SQLSTATE[22003]: Numeric value out of range| +---------------+----------------+--------------------------------------------------+ As an example in Apeisas Shoppingcart Module exists a field sc_price of type float(). This field allows a maximum value of 9999.99 Euro Dollar or whatever. Don't use it to sell cars like Ferrari. Try to store the input values of the preceding table in a PW Field of Type Float in your surrounding and look what you get after saving. Threads treating the same problem https://processwire.com/talk/topic/3888-float-field-rounding-problem/ https://processwire.com/talk/topic/86-float-field-rounding rounding Mysql will round anyway the float value to precision. So it is not necessary to round the value in php before storing. To store exact Values it is better to use Type decimal(M,D) where M is the lenght and D the number of digits. Thread treating the same problem https://processwire.com/talk/topic/86-float-field-rounding format We had already some discussion about local settings, storing and output of PHP-Values of Type (float). And Ryan did some Adjustments with number_format. But I don't trust completely, thats why I am using Textfields to store numbers. Would be nice to have a consistent Fieldtype working in different local-settings. Thread treating the same problem https://processwire.com/talk/topic/4123-decimal-point-changed-to-in-base-of-setlocale/ https://processwire.com/talk/topic/86-float-field-rounding What is a float (floating point value), what is decimal? A float is an approximate value and exactly like this it is stored in Mysql. For more understanding two examples. 1. example CREATE TABLE `test` ( `test_float` float(10,2) NOT NULL, `test_decimal` decimal(10,2) NOT NULL ); INSERT INTO `test` (`test_float`, `test_decimal`) VALUES (5.43, 5.43); SELECT (test_float * 1.0000000) AS f, (test_decimal * 1.0000000) AS d FROM test; This will result the following: f = 5.4299998 and d = 5.430000000 source: http://netzgewe.be/2012/03/mysql-und-waehrungsbetraege-float-vs-decimal/ (german) 2. example mysql> create table numbers (a decimal(10,2), b float); mysql> insert into numbers values (100, 100); mysql> select @a := (a/3), @b := (b/3), @a * 3, @b * 3 from numbers \G *************************** 1. row *************************** @a := (a/3): 33.333333333 @b := (b/3): 33.333333333333 @a + @a + @a: 99.999999999000000000000000000000 @b + @b + @b: 100 source: http://stackoverflow.com/questions/5150274/difference-between-float-and-decimal-data-type INFO & LEARNING http://stackoverflow.com/questions/5150274/difference-between-float-and-decimal-data-type http://stackoverflow.com/questions/4520620/float-precision-problem-in-mysql http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html INTENTION The intention of this thread is to discuss good solutions for a consistent working FieldtypeFloat which makes clear to Everybody what it is via description. Furthermore to build a new Fieldtype with setting options of total lenght and decimal places. NOTES Please use this thread rather for development than as a help forum. BTW I am not an expert in Mysql PHP or whatever. Maybe there are some guys in the forum which could put the real good stuff here. Thanks a lot and lets go.1 point
-
File Info A textformatter module for ProcessWire. The module can add information to local Pagefile links in two ways: As extra markup before, within or after the link As data attributes on the link (handy if you want to use a Javascript tooltip library, for instance) Screenshots Module config Example of output Installation Install the File Info module. Add the textformatter to one or more CKEditor fields. Configuration Add markup action (and general) Select "Add markup to links" Select the Pagefile attributes that will be retrieved. The attribute "filesizeStrCustom" is similar to the core "filesizeStr" attribute but allows for setting a custom number of decimal places. If you select the "modified" or "created" attributes then you can define a date format for the value. Enter a class string to add to the links if needed. Define the markup that will be added to the links. Surround Pagefile attribute names in {brackets}. Attributes must be selected in the "Pagefile attributes" section in order to be available in the added markup. If you want include a space character at the start or end of the markup then you'll need >= PW 3.0.128. Select where the markup should be added: prepended or appended within the link, before the link, or after the link. Add data attributes action Select "Add data attributes to links" Select the Pagefile attributes that will be retrieved. These attributes will be added to the file links as data attributes. Attributes with camelcase names will be converted to data attribute names that are all lowercase, i.e. filesizeStrCustom becomes data-filesizestrcustom. Hook If you want to customise or add to the attributes that are retrieved from the Pagefile you can hook TextformatterFileInfo::getFileAttributes(). For example: $wire->addHookAfter('TextformatterFileInfo::getFileAttributes', function(HookEvent $event) { $pagefile = $event->arguments(0); $page = $event->arguments(1); $field = $event->arguments(2); $attributes = $event->return; // Add a new attribute $attributes['sizeNote'] = $pagefile->filesize > 10000000 ? 'This file is pretty big' : 'This file is not so big'; $event->return = $attributes; }); https://github.com/Toutouwai/TextformatterFileInfo https://modules.processwire.com/modules/textformatter-file-info/1 point
-
Or if you are only supporting recent'ish versions of PW: urls()->$this . 'script/test.js';1 point
-
great! thx soma! this is also possible and imho the cleanest solution: config()->scripts->add(config()->urls($this) . 'scripts/test.js'); thx ?1 point
-
Or you can even use the class name too config()->scripts->add(config()->urls->{$this->className} . 'scripts/createInvoiceButton.js');1 point
-
I am glad you started a thread on this topic. I agree it would be great to see a FieldtypeDecimal module shipping with the core. This is something that's actually on a TODO-list for a big project of ours. It should definitely be a separate module (in other words, leave FieldtypeFloat alone) because floats have a different purpose. The background of the problem is in how computers handle (or should you say, how they support handling) floating point values. It actually doesn't have anything to do with PHP or MySQL, even less with PW - although you can obviously feel the effect of it. Binary floating point values supported by the CPU/ALU/FPU, such as the commonly used IEEE 754 (C, Java, PHP and so on), are always approximations. They are used where speed matters the most and the tiny loss of precision is acceptable. When precision is needed, you actually need something that implements arbitrary-precision arithmetic (bignum). The resulting loss of speed is irrelevant in many cases, such as handling currency. The reason why I'm bringing this up is that even with a FieldtypeDecimal implementation, you would still need to make sure you are handling the values correctly in PHP. If you perform any arithmetic on the value using PHP's arithmetic operators, you are actually causing PHP to cast the value to a floating point representation. That would defeat our purpose here (because you could loose precision). Thus if you need to perform arithmetic on the value, you must use an arbitrary-precision arithmetic library. For PHP you have at least two good options BCMath - http://php.net/manual/en/book.bc.php (simple set of functions, built-in) GMP - http://php.net/manual/en/book.gmp.php (a much larger set of functions, requires an external library) Of course none of this matters unless you can first store the original value in the database without precision loss. This requires a DECIMAL field in MySQL - which indeed was the original topic of the thread Here's a few links for general information. I recommend you to read at least the first one - it's a simple introduction. http://floating-point-gui.de/ http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic http://en.wikipedia.org/wiki/Double-precision_floating-point_format http://en.wikipedia.org/wiki/Fixed-point_arithmetic1 point