Listing folder contents into a json

Hi,

I'm having some problems on listings folder contents into a json, here is what I'm doing but without success, I've tried every think I know but cann't do what I need... I need to get a list o object to a json to use it on a external web site..

from Products.PythonScripts.standard import html_quote
from Products.CMFCore.utils import getToolByName

plone_utils = getToolByName(context, 'plone_utils')
mtool = getToolByName(context, 'portal_membership')
urltool = getToolByName(context, 'portal_url')
portal = urltool.getPortalObject()

path = '/Site_sotinco/v2/produtos/'

query = {}
query['path'] = {'query' : path, 'depth' : 0, 'level':0 }
query['portal_type']= 'ATFolder'
query['review_state']='published'
query['sort_on'] = 'getObjPositionInParent'
query['sort_order'] = 'ascending'

#print query

resultados = context.portal_catalog.searchResults(review_state='published',
sort_on='getObjPositionInParent',
path={'query': path, 'level': 0,'depth' :0})

print resultados

json = '['

for item in resultados:
obj = item.getObject()
id = obj.getId()
title = obj.pretty_title_or_id()
familia = obj.getProperty('familia', '')
referencia = obj.getProperty('referencia', '')
link = obj.getProperty('link', '')
text = obj.getProperty('text', '')
produto_origem = obj.getProperty('produto_origem', '')

print link

json += '{"id":"' + str(id) + '"},'

json += json[:-1]
json += ']'

context.REQUEST.RESPONSE.setHeader("Content-type", "application/json; charset=utf-8")

print json
return printed

please use json module of python. Is your example a Python Script added via ZMI?

yes it is, how can I use a json module on plone?

Ok, register a View like described in the Docs.
Your Browser View should contain the JSON-Dump:

try:
    import json
except ImportError:
    # Python 2.5/Plone 3.3 use simplejson
    import simplejson as json

from Products.Five.browser import BrowserView

class ExportAsJSON(BrowserView):

    def __call__(self):
        
        data = []
        for item in resultados:
            obj = item.getObject()
            
            id = obj.getId()
            title = obj.pretty_title_or_id()
            familia = obj.getProperty('familia', '')
            referencia = obj.getProperty('referencia', '')
            link = obj.getProperty('link', '')
            text = obj.getProperty('text', '')
            produto_origem = obj.getProperty('produto_origem', '')
            
            r = {
                "title" : obj.pretty_title_or_id(),
                "familia": obj.getProperty('familia', '')
                # and so on....
            }
            
            res.append(r)
            
        pretty = json.dumps(data)
        self.request.response.setHeader("Content-type", "application/json; charset=utf-8")
        return pretty

where do I put this file? I don't know very much about plone, the developer of the company I work left and didn't let any kind of documentation and I only work here since april.

I've a script working well in the way I show you +/-.. but I cann't make it work for another folder.. it was developed by the other guy :\

If the Script in the Root-Folder of your Plone Instance, then it should working in every Folder.
Example: your Script has the id "json-export"
If your call the url http://yourdomain.local/json-export or http://yourdomain.local/folder1/json-export then your get the Output.
You can't use the JSON Module via ZMI-Script.

so I put the code you gave me on the root of my website ?

The easiest solution is just to instal Plone REST API https://github.com/plone/plone.restapi, but you will not have any control on the JSON content your Plone site will returned (so if you need to list folder contents as JSON, that's just fine, at the contrary if you want to add your own attributes in the response, thta's not possible).

If you need to define by yourself what your JSON endpoint returns, but you do not want to develop your own Plone module, you can use Rapido https://github.com/plomino/rapido.plone, it can be entirely controlled online from the theming editor. It provides a REST API, and you can implement yourself a JSON content as a block element (see http://rapidoplone.readthedocs.io/en/latest/rest.html#compute-an-element).
Note: it only works on Plone 5.

1 Like

No, not my Code, your Script that you posted.

My script doesn't work.. I don't know why I cann't get the element of the folder

from Products.PythonScripts.standard import html_quote
from Products.CMFCore.utils import getToolByName

plone_utils = getToolByName(context, 'plone_utils')
mtool = getToolByName(context, 'portal_membership')
urltool = getToolByName(context, 'portal_url')
portal = urltool.getPortalObject()

path = '/Site_sotinco/v2/produtos/'

query = {}
query['path'] = {'query' : path, 'depth' : 0, 'level':0 }
query['portal_type']= 'Produto'
query['review_state']='published'
query['sort_on'] = 'getObjPositionInParent'
query['sort_order'] = 'ascending'

resultados = context.portal_catalog.searchResults(query)

"resultados" is empty..

check this:

from Products.PythonScripts.standard import html_quote
request = container.REQUEST
response =  request.response

# Return a string identifying this script.
folder_path = '/'.join(context.getPhysicalPath())
query={
    'path':{'query': folder_path, 'depth': 2},
    'portal_type':'Produto',
    'sort_on':'getObjPositionInParent',
    'sort_order':'ascending'

}
results = context.portal_catalog.searchResults(query)


for result in results:
    print result['Title']
return printed

1 Like

Yes it's working, thank you so much.

What is the "depth" params doing?

The depth of search in a Folder

if you in folder1 then the search-depth is by "2"

folder1/subfolder1/blub1
folder1/subfolder1/blob1
folder1/subfolder2/blob1
folder1/subfolder2/blob2

if you in folder1 then the search-depth is by "1"

folder1/subfolder1
folder1/subfolder2

ok thanks

And another question to complete:

I've the folder produtos

with a lot of "Produto".

Produtos/X/associar_produto like the picture above:

And my script is:

from Products.PythonScripts.standard import html_quote
request = container.REQUEST
response = request.response

Return a string identifying this script.

folder_path = '/Site_sotinco/v2/produtos/construcao-civil/'
query={
'path':{'query': folder_path, 'depth': 2},
'portal_type':'Produto',
'sort_on':'getObjPositionInParent',
'sort_order':'ascending'

}
results = context.portal_catalog.searchResults(query)

json = '['
for result in results:
obj = result.getObject()
title = obj.getProperty('title', '')
referencia = obj.getProperty('referencia', '')
id = obj.getId()

json += '{"id" : "'+id+'" ,"title":"' + title + '", "referencia":"' + referencia + '" },'

json = json[:-1]
json += ']'

context.REQUEST.RESPONSE.setHeader("Content-type", "application/json; charset=utf-8")
#context.REQUEST.RESPONSE.setBody(json, lock=True)
print json
return printed

Tanks to you my script is know working the I need to add the properties from the "Associar_Produto" for each produto, can you help me ?

Mean you this - a complex for-loop?


for produto_brain in produto_brains:
    produto_object = produto_brain.getObject()
    produto_object_path = '/'.join(produto_object.getPhysicalPath())
    query={
       'path':{'query': folder_path, 'depth': 1},
       'portal_type':'Produto',}

    sub_produto_brains = context.portal_catalog.searchResults(query)
  
    produto_properties=[]  
    for sub_produto_brain in sub_produto_brains:
        obj = sub_produto_brain.getObject()
        zona = obj.getProperty('zona', '')
        area = obj.getProperty('area', '')
        # and all other properties like area, caracteristica
        if zona not in produto_properties:
           produto_properties.append(zona)
  
    # produto_properties contain all properties of subprotudos
    # append it to json construct via join list
    produto_properties_as_string = ','.join(produto_properties) 
    json += '{"id":"' + str(id) + '", "props": " + produto_properties_as_string + "},'

I don't know if its a complex for-loop,

I only have 1 "associar_Produto" for each "produto"...

inside my for-loop I should get the properties of the object/associar-produto

obj = result.getObject() <- it have a "associar-produto" with 3 properties

for result in results:
obj = result.getObject()
title = obj.getProperty('title', '')
referencia = obj.getProperty('referencia', '')
id = obj.getId()

json += '{"id" : "'+id+'" ,"title":"' + title + '", "referencia":"' + referencia + '" },'
json = json[:-1]
json += ']'

http://docs.plone.org/develop/plone/content/listing.html#listing-the-folder-items-using-portal-catalog