New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
com_ajax: Changes response format #1960
Conversation
Yes, this change should definitely by merged into master! A bit offtopic: About the 'close' thing. header('Content-Type: application/json'); because Joomla! does that for you (if you don't close the application). |
Couple of things I'd like to change:
|
These changes make sense to me. I was also thinking that a 404 makes more Best, Matt Thomas Sent from mobile. Please excuse any typos and brevity.
|
I've decided to include HTTP response header in case Exception happened and format is other than JSON or debug. When client would request other available formats (Feed, Image, XML or other), response in Raw could break the client-side parser and we don't know how to construct proper one. |
Thanks for taking that with the app closing into account. Maybe a bit more offtopic, but since Ajax requests with format=json will will most probably be used much more in future because of that I want to point to that discussion: |
If |
@betweenbrain Agree, debug is a non-standard format and without closing the application system would fall back to What if we would use it along with 'default' in the switch, so there would be:
like that: switch ($format)
{
// Echo JSON format and break
case 'json':
echo new JResponseJson($results, null, false, $input->get('ignoreMessages', true, 'bool'));
break;
// Anything but JSON is just echoed
default:
// Format to string and add header if it's an exception
echo $results;
// Break for supported documents, these will be handled by JDocumentXxx
case 'raw':
case 'html':
break;
// Close app for non-supported formats
case 'debug':
default:
$app->close();
} |
@Chraneco maybe @nikosdion may have idea about SEF and non-Html formats (ARS + XMLs) |
@Chraneco For json, this isn't such a big deal since those URLs usually aren't created as SEF URLs. They are hidden from the user in an AJAX call somewhere and don't need to be SEF friendly. |
I do agree with @Chraneco that it needs to be resolved, but I don't think this is the place to discuss it. Is there a PR where we can discuss it directly? |
@piotr-cz for the
As that provides a human-readable format. I've found that to be very useful during development. |
@betweenbrain PR for the DocumentType issue: #488 |
So this is an updated version. One thing to remember is that if you'll requesting an HTML format or any that doesn't have own JDocument renderer, switch ($format)
{
// Echo JSON format and break
case 'json':
echo new JResponseJson($results, null, false, $input->get('ignoreMessages', true, 'bool'));
break;
// Pretty print
case 'debug':
print_r($results, true);
$app->close();
break;
// Anything else is just echoed
default:
// Format to string and add header if it's an exception
echo $results;
} |
I'd need to test this further, but I think what you have at https://github.com/piotr-cz/joomla-cms/blob/0326129aef79e3c9c08d1388b58c23241c48eea0/components/com_ajax/ajax.php#L106 is great, except for needing
Does that make sense? |
@betweenbrain yeah, I realized I'm back there. Agree about closing application for 'debug' format, but not by default. Let's say we'd like to receive an image with applied filters:
Now, maybe we have to close the app for HTML and non-supported formats or system will spit whole page with a template. I'm not sure we can rely on '&tmpl=component' because it's in control of template. |
Ah, okay. Yes, that makes sense and sounds good. I agree that we probably do need to still close the app for HTML and non-supported formats, as raw, but not by default. Thanks! |
The switch part became quite ugly now. |
I don't think that it is necessary to close the application for 'debug' and 'raw', in fact it is never necessary to close the application. Format 'raw' does not add any output to the one of the component and for generic formats like 'debug' (for which no document type is given in 'libraries/joomla/document/') there is a fallback to 'raw'. The only case where we can think about adding the closing of the application is when the developer has forgotten to add 'format=anything' to the request URL (thus $format is empty) because then Joomla! assumes format=html. If you ask me I would never add closing the application because forgetting format=anything is the developer's fault. |
@Chraneco That makes sense to me. I think these should be shown only to extension developers, so I'd:
|
It makes sense to me too, but at the same time want to provide raw as the default if the |
In other words, it makes sense for Joomla to generally assume @piotr-cz If I haven't expressed it clearly already, I like your new approach for the error/exception handling. |
@betweenbrain Yes, default to The process is:
The We could change the system default format to raw for ajax requests, and then default to So change the // Check for explicit request format
$type = $input->get('format', null, 'word');
// When no format provided
if (!$type)
{
// Use Html or Raw for ajax requests.
$type = (strtolower($input->server->get('HTTP_X_REQUESTED_WITH', null, 'string')) != 'xmlhttprequest')
? 'html'
: 'raw';
} |
@piotr-cz Changing JFactory::createDocument to have a different default for Ajax requests is a very intriguing idea. It makes sense to me to have different defaults for different request types. |
I tried to change the document type once in my component and came to the conclusion that it's impossible to do. It was possible in J1.5, but isn't possible since 1.6 (I think). The only way to change it is using the Imho, we should rely on the developer using com_ajax to use the format parameter properly. Closing the application early is basically a hack in itself. We should not try to fix errors from lazy developers :-) |
The new approach for error/exception handling seems to be fine for me, too. I also think that we shouldn't change JDocument or JFactory just for com_ajax. I still think that closing the app is not necessary (@Bakual: I fully agree here), but if the majority is for having format=raw the default, it will be the best to just add if(!$format)
{
$app->close();
} below everything. This way you can delete this part // Check for compatible JDocument formats
if (!in_array($format, array('feed', 'image', 'json', 'opensearch', 'raw')))
{
JResponse::sendHeaders();
echo $out;
$app->close();
} and simplify the switch part again. |
Indeed, we need solid test results that demonstrate the benefit of these changes before they are committed. Keep in mind that the code originally contributed, including the I'm all for improving it and will try to do some tests today. I'd also suggest pinging the original tracker item for testers as I think a couple of people on that item have created extensions to use com_ajax. |
I would be in favor of doing it the Joomla way. Not because it is broken now, but because it is a core component now. And those component are also used as examples for developers how to write extensions. Having a simple component supporting multiple formats would be a welcome example addition to the core imho :-) I don't think the debug format is really needed, but we sure can keep it.
An important point to consider: If people are already using com_ajax, they do it at their own risk. It's in an alpha state at the moment and if there is one time in the Joomla lifecycle where you can easily change the API and do backward compatibility breaks, it is now. If you want to do it the proper way, do it now. After release you will be stuck to it and can't do such changes anymore. I would even suggest to change it before beta or during early beta, as developers like me don't like changes in APIs shortly before release (they tend to get in without proper tests) :-) |
I've updated the tracker. |
@Bakual Yes, my reason for referencing the other tracker was not about BC changes, but to get more testers and feedback. Now is definitely the time to make changes, and I'm happy to see it happening 👍 Don't gt me wrong, I firmly believe that core components need to demonstrate best practices. I don't think everything needs to be MVC, they can be MC, but that is a topic for another thread. I do agree that having a component in core that supports multiple formats would be a nice. @piotr-cz Sorry, I must have missed that about the messages. I think they need to be translatable. |
@betweenbrain Why do you think so? There is a difference to Joomla messages (like form errors) in that these won't be shown to a end user (unless (s)he decides to mess with the system). |
On the topic of the translated Exceptions, generally in the libraries, we've moved to static English for all Exceptions and log entries, with some exceptions. The primary reason is that these sources are geared more towards developers and troubleshooting and less towards front end users and seeing errors. Developers should be catching Exceptions and deciding what to do (is the Exception fatal to processing or can you go on with only a note about the failed condition?). Rarely should you be catching the Exception and directly throwing its message right back out to a user, but if you have a valid case where you're doing that, then make it translatable. |
It was for the longest time. Then the Platform came along and started decoupling dependencies between packages, with the big one being why was EVERY package dependent on JText. Personally, I think that (and moving away from JError in general) is the right move; it requires you to think about everything more in your code, including error handling. |
Thanks for the explanation, that helps allot. Frankly, I'm behind on most of this as nearly all of my work for the last year has been focused on 1.5, and will be for some time still. |
@piotr-cz What do you think about replacing Shouldn't the closing of the app for |
@Chraneco The code would definitely be more readable and as you say flexible. |
That's also pretty similar to what i have been doing elsewhere. format= I don't know if you saw but I proposed a general controller helper which i Elin On Thu, Sep 19, 2013 at 6:52 AM, Piotr notifications@github.com wrote:
|
@elinw Fedik suggested to rewrite the code to MVC and I'm personally very in favor of that (see his branch). I'd like that to be separate PR after this one is merged, because it took some discussion to get into current state and we could discuss that thing separately. PS send me some info about component helper you mentioned |
JLog::add($results->getMessage(), JLog::ERROR); | ||
|
||
// Set status header code | ||
JResponse::setHeader('status', $results->getCode(), true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now @mbabker 's JApplication changes have gone through we shouldn't be using JResponse anymore but the JApplication alternative
I think that the default format |
Don't make it to complicate. I you need a html response and the tmpl=component parameter doesn't work you can always use format=raw and output whatever you need with the appropriate headers. If you would not render the template you will not get a valid HTML document anyway. |
@Fedik My explanation of Using |
Please resync this PR to master. |
…patch_com_ajax
Resynced to master |
Original PR: #1778
Tracker: #31980
As per discussion: JGEN: Joomla Ajax Interface, now new class JResponseJson is used to build a structured response.
Response
Exception in com_ajax or thrown/ returned by Module/ Plugin/ Application
Additionally I've added options:
ignoreMessages
(boolean, defaults to true): Set the JResponseJson to ignore dumping system messages into response->messagesclose
(boolean, defaults to false): Close the applicationIn this patch Ajax Plugins are not expected to return anything - in the previous version this evaluated to an error 'plugin returned no response'.