-
Posts
680 -
Joined
-
Last visited
-
Days Won
18
Everything posted by Jan Romero
-
Since you have the codes separated by spaces, word matching selectors may work well for you. Check out “~|= Contains any words”, “**= Contains match” and “~= Contains all words” in particular. You could also hook after Pages::savedPageOrField and transform the textual list into page references whenever it changes.
-
Are you on the latest version? That looks very similar to the error I mentioned above.
-
Mh, this might be a ProcessWire bug? This configuration causes multiple database queries to be executed. The query you end up with contains a list of all pages that reference the "Global" report_type. To get this list, a different query is run beforehand and that one doesn’t seem to get the right results for guest users. I assume this is because guests don’t have access to the repeater pages (a hidden page called "Repeaters" under the "Admin" branch), but I haven’t been able to figure it our completely. As a workaround, you can use "include=all" instead of "check_access=0", but be aware that this may have unintended effects because it will find pages that are hidden or unpublished. You can also get the IDs yourself and use them like so: $ids = pages()->findIDs('template=report_type, title=Global'); //adjust selector according to your setup $reports = pages()->find('parent.name=reports, report_meta_details.report_type=' . implode('|', $ids)); //note: don’t use “report_type.id=” Can you confirm that your "report_type" pages have no access restrictions and are not hidden or unpublished?
-
This surprises me. To debug this, it may be useful to look at the generated SQL. You can do this easily with Tracy Debugger (I guess you would have to enable it for guests temporarily?), but you can also do it in code:
-
BTW, you don’t need write “name=” here, $pages->get('reports') should be sufficient, unless you like the added clarity.
-
[SOLVED] How to manage image field with hundreds of images?
Jan Romero replied to charger's topic in General Support
Almost exactly 6 years ago Ryan released pagination support for ProFields Table and was thinking about implementing this for more Fieldtypes such as Images: https://processwire.com/blog/posts/fieldtype-pagination/ Unfortunately this hasn’t happened yet, so maybe commission a website from Ryan that involves 600 images per page and he'll prioritise the feature ? The first thing I would do to remedy the immediate problem would be to move the images to a separate tab in the page editor. That should keep the loading times down when you just want to change some other stuff. Otherwise, I guess you’ll have to build a custom Inputfield (perhaps without thumbnails) or structure your site differently. Here is a longish thread about turning off the Image field's auto-thumbnails, maybe it has some pointers relevant to your endeavour: https://processwire.com/talk/topic/21112-do-not-create-default-image-variation-on-image-upload/ You could also try using a Files field instead. I imagine the page editor performance will be better and it won’t auto-generate thumbnails. Of course, you’ll have a harder time scaling and using the images in the front-end. Check this thread for more info https://processwire.com/talk/topic/26113-resize-image-manually/ -
@bernhard Admittedly, I had never really paid attention to php://input, so this thread prompted me to google it. As I understand it, that stream always contains the raw request body, so anything could be in there, however only two content-types end up in $_POST and thus also in PW’s $input->post: application/x-www-form-urlencoded and multipart/form-data. For these, in addition to sorting everything into an associative array, PHP also takes care of unescaping the URL encoding. When OP wants to send Json, I’m assuming he quite sensibly declares application/json. PHP doesn’t know this content-type (plus, the whole thing is a nameless Json object, so what would be the key for $_POST’s associative array?), so nothing happens automagically. This answer on SO gives a lengthy overview on how to handle php://input. If you’re asking about the client-side fetch() API, I have to confess I didn’t test the code I posted, but the idea is to create a request with the content-types application/x-www-form-urlencoded or multipart/form-data mentioned above. Indeed, for some reason I thought it would be necessary to specify the former content-type, but it’s actually set automatically when URLSearchParams are used for the request body (at least in Firefox). Likewise, when the body is of type FormData, the default content-type will be multipart/form-data. As for when to send a body, it’s just the HTTP request’s content, so I guess whenever you want to transmit data to the server, i.e. usually with POST (or PUT or something). When dealing with third party APIs you gotta do the weird things they want you to, of course. If it’s your own PHP/ProcessWire site you send requests to, I’d say it doesn’t really matter whether it’s application/x-www-form-urlencoded or multipart/form-data (or URLSearchParams or FormData for that matter), since both deliver keys and values that end up in $_POST/$input->post. In this case I would just use whatever is more convenient to assemble in JS, i. e. if the data actually comes from a HTML form, you can pass the form element to FormData’s constructor and you’re done. Sorry if I’m not telling you anything new here ? Trial and error makes up a large chunk of my modus operandi as well m)
-
Well, you can just send your POST request in such a way that the Json will be available as $input->post['myData'], that is, as FormData or UrlEncoded: fetch('https://example.com', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' }, body: new URLSearchParams({ 'myData': JSON.stringify(someObject) }) }); or const formData = new FormData(); formData.append('myData', JSON.stringify(someObject)); fetch('https://example.com', { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest' }, body: formData }); If your object is just a simple key-value affair, you may actually want to send it that way and not as Json at all, because you’ll be able to use the sanitizer methods for each value. With the Json you have to parse it and then sanitize the properties, watch out for properties you didn’t want etc.
-
Btw you may want to check $form['email'] instead of the raw input, because it’s sanitized. If your user enters an invalid email, your current code won’t catch it. The sanitizer will return an empty string if it doesn’t think the input is valid, so checking the sanitized value will also catch invalid input even if it’s not empty.
-
This doesn’t happen after you set the error, by any chance? If that’s not it, try posting the whole code up until the point where the error should be displayed. Also, I would probably prefer to access the email field like this $input->post('email') because $input->post->email() is also the name of a sanitizer method.
-
form mailer: sanitizer->date how to format output of the date
Jan Romero replied to wishbone's topic in Getting Started
Huh, sorry, I thought ProcessWire would figure out the arguments automatically, since their types are distinct. It usually does that. Try passing null in the second argument: $sanitizer->date($input->post->termin1, null, ['returnFormat' => 'd.m.Y']); (Sorry, I’m on vacation, no code formatting on mobile) Anyway, as I understand it, the first parameter is the format you expect the incoming value to be. A sanitizer’s job is generally to make sure the input conforms to some expectation. In this case you don’t care what format the input is, so you don’t tell it your expectation and it will just try to make any valid date out of the input. Additionally you specify the returnFormat to get a pre-formatted string back (this is not always desired because often dates need to be used in calculations or be checked against additional logic). Be aware you might still get null if the input can’t be made into a valid date. Also, if the input is in an ambiguous format, it may get parsed in an unexpected way (in fact, sometimes it seems to default to the current date). But this shouldn’t be a problem because AFAIK browsers all send YYYY-MM-DD when a date input is used. It’s just to say that it’s usually good practice to specify the input format. -
form mailer: sanitizer->date how to format output of the date
Jan Romero replied to wishbone's topic in Getting Started
Hi, as per the docs you can specify the return format in $sanitizer->date(), just not quite the way you have done it (https://processwire.com/api/ref/sanitizer/date/). This should do the trick: $sanitizer->date($input->post->termin1, ['returnFormat' => 'd.m.Y']); -
Infinite loop through sibling pages based on template
Jan Romero replied to Peter Knight's topic in General Support
Ah, nice, definitely! I was hesistant to use the WireArray first() and last() functions, because I wanted to avoid loading all siblings. Not sure if that’s really a concern, though? -
Infinite loop through sibling pages based on template
Jan Romero replied to Peter Knight's topic in General Support
This could be a job for the Elvis operator: //if $page->prev-path is empty, get the path of the parent's last child (sorted by sort descending), i.e. loop around to the end echo "<a href='" . ($page->prev->path ?: $page->parent->child('sort=-sort')->path) . "'><i class='fas fa-arrow-left'></i></a>"; //if $page->next-path is empty, get the path of the parent's first child, i.e. flip over to the beginning echo "<a href='" . ($page->next->path ?: $page->parent->child->path) . "'><i class='fas fa-arrow-right'></i></a>"; Btw in your if-condition you're checking for the next and previous sibling of a specific template, but you output the next/previous sibling without this restriction, so if you have mixed templates in this branch of your page tree, you may get unexpected results. I've left out the template conditions in my snippet above, you may want to add them in the appropriate places. -
By default, ProcessWire will prevent you from running subcruberList.php like that (you will get error 404 or 403). What you can do is create a ProcessWire template and set subcriberList.php as its template file. Then create a page with that template and do your POST request to that page. There are a couple of threads in the forums about handling forms that may be of help. Also consider using a form module such as FormBuilder.
-
Hi, welcome to the forums! Are you using ProcessWire for this? It looks like you’re submitting your data to a file called “subcriberList.php”. Can you elaborate on where this file is and what it does?
-
@ryan Have you considered putting some new screenshots here? It’s a very popular feature judging from showcase threads, developers here love to show off their images to great effect (it was also asked about in this recent thread, for instance), but it gets almost no love in the public docs/store page, and even in the introductory blog post it can only be seen for a split second in the video. The images in the video are also kind of grey in comparison to @olafgleba’s beautiful display ? I’m sure showing it off on the store page would boost sales some!
-
These always trip me up, I get all excited by a big blog post and then it turns out I already know everything from following your lovely weekly threads ? Great stuff as always!
-
Use API to remove item by id from repeater on a specific page
Jan Romero replied to PascalKonings's topic in API & Templates
Repeater fields give you a PageArray. Have you tried getPageByID($id) to retrieve the item? Check the return value before removing. It might be NullPage, or when using get() it might be null. As a matter of fact, since you already know the ID, it should be perfectly safe to just delete the page: $pages->get($id)->delete(); -
@fruid Admin pages are just pages in the admin branch of the tree. The ones ProcessWire ships with as well as those of some modules (e.g. Adminer) use a special admin template, but you can just put any old page there. So I would just make a new template with the things you need and create a new page under Admin and set it to hidden and unpublished. When the form is submitted you can get the page by its ID, add the submitted data to it and save.
-
Well, once you have the submitted data, you can do with it whatever you want. It really depends on what the data is and where you want it. In my comment above the example is one email address and one comment. So if you want to store those things in your admin page, its template would need a way to store multiple email-comment pairs. That could be a Repeater or a ProFieldsTable (?) or a custom fieldtype. You could also store one new page per submission as a child of your admin page (that’s essentially what a repeater would do behind the scenes anyway, it just looks different in the page tree and page editor – pretty much a matter of preference). Having a page per submission takes care of some stuff you probably want anyway automatically, such as storing the creation date. It also gives you a url for each submission that you could put into an email notification for yourself, or something. My comment gives a pretty complete example of how to get the data from the user’s browser into ProcessWire’s database. Are you struggling with anything specific?
-
I can't upload file through a form uploader.
Jan Romero replied to sam13579's topic in General Support
Hi. You're using $input->get('doc') in a couple of places, but the files are sent in a POST request. Also, check out this thread, especially the bit about "new WireUpload()": Additionally please note how the code blocks are formatted in that thread. Please do the same when posting lengthy code excerpts. You can click the button labelled "<>" above the text editor to insert a code block and even choose the programming language there. -
anybody could show an example of how to use $config->ajax ?
Jan Romero replied to adrianmak's topic in Getting Started
In addition to the other very valid comments, this is what’s causing the problem as I understand it. ProcessWire will still prepend _init.php for Ajax requests unless you tell it not to. One way might be to wrap these two lines in an if-block in config.php. That will disable the prepend/append files for all Ajax requests, which seems reasonable: if ($config->ajax) { $config->prependTemplateFile = '_init.php'; $config->appendTemplateFile = '_main.php'; } A more flexible approach may be to forego auto-append and just call those files explicitly when you want them. To expand on @szabeszs comment, $config->ajax works by detecting the header “X-Requested-With”, which browsers don’t send by default. If you’re using XMLHttpRequest, you need to add it like this: var request = new XMLHttpRequest(); request.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); If you use the Fetch API, there is a Headers() object you can pass: https://developer.mozilla.org/en-US/docs/Web/API/Headers Jquery sends the header automatically, which is. I believe, why ProcessWire expects it. -
Perhaps you can just run your code after saving? $wire->addHookAfter("Pages::saved", /* … */); Also worth noting is the hook Pages::savedPageOrField.
-
[SOLVED] Float field type problems more than 6 numbers
Jan Romero replied to formulate's topic in Getting Started
+1 for installing Decimal by default and perhaps even making Float uninstalled by default.