So I'm submitting a feature request patch for the views.get service. I have looked over some threads, such as #654644: views.get method changed in DEV version and #415314: Get filename and filepath from Services views.get, and it seems like this has possibly come up from others before, but in the case of #654644 it seems to have evolved into a discussion regarding displaying a View row as a node.
My request is to be able to setup a View with the "fields" row style and be able to put the rendered values of the fields into the output of the service. From what I've been able to figure out so far, if I use Services to get a View that has a fields row style, the output seems to be a pre-rendered version of the nodes. For example, if I have a field that is supposed to output the URL of a specific imagecache setting, I instead get the fid of the original image.
This patch basically uses each field's theme function to get the content, but without using the format_output option since that will add all sorts of markup I can't use. I also made it use the field's label as the property name. This way, if you have multiple fields in your View that are from the same source, they can have different property names based off of whatever is put in the field's label.
Any thoughts? Is this useful enough to others to add? Patch to follow.
Comments
Comment #1
jonmcl commentedThe patch....
Comment #2
marcingy commentedThis won't go into 6.x.2 as it is feature frozen moving to new services views project, so as it can be considered for 3.x.
Comment #3
dragonwize commentedI think the base idea here is great and quite needed. However, there are some areas that need improvement.
Comment #4
kylebrowning commentedIt be nice to see a newer patch that works. with the suggested changes in #3
Comment #5
apotek commentedTrying to write this patch and am having difficulties finding the "official" best way to dynamically handle the fields row rendering. The view, by default, only returns data directly attached to the node, not any of the fields data, nor any of the formatting of those fields that a default views display will give.
Can anyone point me in the direction of the best documentation on this, or which hooks to look at?
Comment #6
apotek commentedI see the technical point you are trying to make, however, if a creator of a view wants a property named something, then we should respect that name, and not override it because we want to protect the creator from the folly of including non-allowable characters in his or her label (object property). Sticking to the field alias, afaik seems to have its own issues: 1) There will be a host of tickets opened in the ticket queue from users saying "Why doesn't my label show up in the view when downloaded as json?" 2) The field_alias, in my last two weeks of experimentation, have revealed themselves as being wrongheaded too. Consider the field alias of a field that has been set up on the view to have a url to an image linked to via fid.
Result:
In this case, the field_alias is entirely off when it comes to describing in any meaningful way, what is being rendered by the view. Why should this value be called node_vid?
Alternatively, we can use the field id, but this leads to similarly non-sensical results:
Given this, I think it's best to use the label requested by the creator of the view. If that leads to problems for that view's usability through services, then the creator of the view needs to adjust the labels accordingly.
Alternatively, we could also use the label, and strip it of any illegal characters.
#################
I think this default is entirely appropriate, and follows the model outlined in this code:
No "views metadata" is being served along with the nodes here either, and this was committed code in services_views.
The question here is what it means to retrieve a view. Are we retrieving the result of the view, or the view itself? It looks to me that most use cases would be returning a list of results from a view rather than a construct of a view. I am not even sure how useful the views metadata would be in a service context--other than for export/ingestion into another site that wanted to replicate that view.
##########
I'll have to rip apart more than I really want to dare to in services_views_retrieve to do this.
##########
I don't know enough to know what this means. Sorry.
Anyway, here's my patch, which addresses none of your desires, but which addresses the desires expressed by the opener of this thread: "Allow views.get to return rendered fields for 'fields' row style".
I haven't seen any issues opened for views computed fields or returning rendered fields for non-node-related fields. I do see the utility of this, but again, in order to generalize this, it seems to me that the whole of services_views_retrieve would have to be refactored. Let me see if I can put some thought into that.
Comment #7
apotek commentedAnd here it is.
Comment #8
apotek commentedRenamed $node to $item. This code is really not only being triggered when the results are nodes. It's entirely based on the row_plugin value.
So the remaining item, I guess, is to make this happen also for this case?
Comment #9
apotek commentedToo late in the day. Pls ignore 5 and 6.
Comment #10
raidcha commentedHi,
thanks for this very usefull patche.
the last patch views_service.inc-views.get_fields-1131194-7.patch doesn't work. it returns empty json like: [{},{},{}]
But the patch views_service.inc-views.get_fields-1131194-6.patch works great.
Comment #11
apotek commentedThanks raidcha. Here's the latest working version.
Comment #12
apotek commentedIs this rewrite what you mean? Will this ensure that the row_plugin gets applied regardless? With the code below, the fields row plugin would be invoked by anything that wasn't a return type of view and whose row style is not 'node'.
Comment #13
apotek commentedThinking about this field label thing and how the field id and field alias are not good substitutes for most field-based data.
I could create a dependency on the wonderful transliterate module and strip out bad characters from the field label. But that creates another dependency.
Could also do some ugly regexing:
Part of the issue here is that different object output formats have different needs for their property names. Anything I would write here would end up being a lowest-common-denominator situation (ie, ascii only).
Is there a general purpose function to be called upon that I could use for this, or should I stick to my previous point that if someone defines a label for a field in a view, intending it to be used as a service, then the user has to be knowledgable enough to make sure those labels will work with the object output format served.
Comment #14
Kunani commentedapotek I patched this into 7 and it gives me:
Cannot pass parameter 1 by reference in services_views_resource on this line:
$field->pre_render(array($row));
Comment #15
Kunani commentedOkay I solved D7 issue by removing the pre_render and render:
$field->pre_render(array($row));
$item->$field_label = $field->render($row);
and replacing with just this THEME Function:
$item->$field_label = $field->theme($row);
Now using FIELDS within views and services 3 I'm getting the output I expected from the very beginning of using this module! I can now control which fields get returned, as well as the labels to match some previous code already accessing these results.
Also previously I had to access CCK custom fields by drilling down through the language UND and VALUE settings, this is no longer needed.
Very happy with this patch and the services module, thanks to all who have contributed.
Comment #16
frazras commentedViews Datasources implements this pretty well, they have a display format that allows you to display as JSON or XML, so u cancustomize the fields only for that display. mmy only issue with it was it did not support JSONP out of the box, the issue queue had some tacked up fixes which were not written as a patch or committed to code. JSONP was essential to be able to use the JQuery getJSON function cross domain. Apotek, you probably could review their methodology and rewrite this to model it.
Comment #17
apotek commentedThis is interesting. It's what I tried to do first (use the theme() function), but it didn't work in D6.
It doesn't look like this will ever get committed to D6 services_views, so maybe you should contribute a separate patch to D7 and see if that will get applied. At least D7 will get this functionality.
Comment #18
apotek commentedThe solution here would be to define the array as a variable first, and then pass the variable, rather than the array directly.
However, I can confirm that this does NOT work in D6. I am unable to get the fully formed field data using
$item->$field_label = $field->theme($row);. The only way I can get the information I need is to useComment #19
apotek commented[deleted duplicate]
Comment #20
kylebrowning commentedComment #21
kylebrowning commented#11 has been applied to 6.x, but needs a port for 7.x :/
Comment #22
kylebrowning commentedI committed the same version with
$item->$field_label = $field->theme($row);instead ofHope that helps!