Forum Discussion

omygoodness's avatar
8 years ago

Retrieve data from XML endpoint

I have custom XML endpoint which looks like this:

<levels>
<level>
<name>LEVEL 1, NAME1</name>
<points>0</points>
</level>
<level>
<name>LEVEL 2, NAME2</name>
<points>10</points>
</level>
</levels>

Now I would like to get this data in custom component. How can I do that? I tried to use rest call but I am not sure which url should I use.

 

My endpoint url looks like this:

https://communityurl/plugins/custom/communityname/communityname/ranking_levels

  • ChiaraS's avatar
    ChiaraS
    8 years ago

    In that case, I would probably just add the details (as json, xml or whatever structure you want to use)  in one of the custom content fields (/t5/bizapps/bizappspage/tab/community%3Aadmin%3Acontent%3Acustom-content) which is not used and get the content from the custom component with rest (https://community.lithium.com/t5/Developer-Documentation/bd-p/dev-doc-portal?section=commv1&leaf-id=Settings.name.name#Settings.name.name )

     

    For ex. for custom content 9:

    <#assign custom_content_9 = restadmin('/settings/name/customcontent.9_text').value />

  • omygoodness- As ChiaraS said, custom content is the best way to do this, I would suggest you to use JSON structure for this. You also can create macro to store your XML or JSON structure in a freemarker variable.
    Thus you can include your macro in any custom content and endpoint to access your XML or JSON structure.

  • Do you mean something like this?

    <#assign custom_content_9 = restadmin('/settings/name/customcontent.9_text').value />

    <#assign test = custom_content_9?eval>

     

    ${test}

     

    And how should I format JSON to be correct?

    For now my custom_content_9 looks exactly like this and ?eval didn't help:

    {
    "levels": [
    {
    "name": "LEVEL 1",
    "points": "0"
    },
    {
    "name": "LEVEL 2",
    "points": "10"
    }]
    }

     Error:

    FreeMarker template error (HTML_DEBUG mode; use RETHROW in production!)

    For "${...}" content: Expected a string or something automatically convertible to string (number, date or boolean), but this has evaluated to an extended_hash (wrapper: f.c.HashLiteral$SequenceHash):
    ==> test  [in template "ranking-test.ftl" at line 5, column 3]
    
    ----
    FTL stack trace ("~" means nesting-related):
    	- Failed at: ${test}  [in template "ranking-test.ftl" at line 5, column 1]

    SOLUTION 

    Ok. I think I have solution :) Custom content with JSON or rather array should look like this:

     

    {
        "name": "LEVEL1",
        "points": "0",
        "name": "LEVEL2",
        "points": "10",
        "name": "LEVEL3",
        "points": "50"
    }

    Then we have ?keys for keys in my case "name" and "points" and ?values for values like "LEVEL1" and number of points

     

    <#assign test = restadmin('/settings/name/customcontent.9_text').value?eval>
    
    <#list test?keys as k>
      ${k}
    </#list>
    
    <#list test?values as v>
      ${v}
    </#list>

    So in the end ?eval worked for me but proper format of data is crucial here.

9 Replies

  • omygoodness - This can be achieved by making an jQuery ajax call to an endpoint. Your endpoint type should be XML in order to get response in XML format.   

    var endpoint_url = "/plugins/custom/communityname/communityname/ranking_levels";
    $.get(url, function(data, status){ alert("Data: " + data + "\nStatus: " + status); });

    If you are not familiar with jQuery you can refer here . 

    Give kudos if you find my posts helpful or mark solution if it answers your query

     

  • ChiaraS's avatar
    ChiaraS
    Lithium Alumni (Retired)
    8 years ago

    omygoodness what's the use case for calling the endpoint from a custom component? I would just move create a macro and call that from both the endpoint and the custom component...

  • omygoodness's avatar
    omygoodness
    Mentor
    8 years ago

    TariqHussainChiaraS I have custom ranks created in ADMIN - USERS - RANKING. Each rank has custom formula which counts user points for topics, kudos etc. 

     

    Now I would like to store points for each rank to count them in such way: NEXT_LEVEL_POINTS - CURRENT_POINTS = POINTS_TO_ACHIEVE and display progress bar. Since I can't create custom field called "points" I need some place to store NEXT_LEVEL_POINTS.

     

    I came up with XML file and rest call to get data using Freemarker and avoid using jQuery but maybe I am looking in wrong place?

    Will macros do the job? Can you tell me more about it?

     

    Example XML

    <levels>
    <level>
    <name>LEVEL 1, NAME1</name>
    <points>0</points>
    </level>
    <level>
    <name>LEVEL 2, NAME2</name>
    <points>10</points>
    </level>
    </levels>

     

  • ChiaraS's avatar
    ChiaraS
    Lithium Alumni (Retired)
    8 years ago

    In that case, I would probably just add the details (as json, xml or whatever structure you want to use)  in one of the custom content fields (/t5/bizapps/bizappspage/tab/community%3Aadmin%3Acontent%3Acustom-content) which is not used and get the content from the custom component with rest (https://community.lithium.com/t5/Developer-Documentation/bd-p/dev-doc-portal?section=commv1&leaf-id=Settings.name.name#Settings.name.name )

     

    For ex. for custom content 9:

    <#assign custom_content_9 = restadmin('/settings/name/customcontent.9_text').value />

  • omygoodness- As ChiaraS said, custom content is the best way to do this, I would suggest you to use JSON structure for this. You also can create macro to store your XML or JSON structure in a freemarker variable.
    Thus you can include your macro in any custom content and endpoint to access your XML or JSON structure.

  • omygoodness's avatar
    omygoodness
    Mentor
    8 years ago

    TariqHussain ChiaraS Thank you for help but I have one more question.

     

    How to loop through json structure which I get by <#assign custom_content_9 = restadmin('/settings/name/customcontent.9_text').value />

     

    My JSON looks like this:

    {
    "levels": [
    {
    "name": "LEVEL 1",
    "points": "0"
    },
    {
    "name": "LEVEL 2",
    "points": "10"
    }]
    }

     

    When I am trying to use it like this:

    <#assign custom_content_9 = restadmin('/settings/name/customcontent.9_text').value />


    <#list custom_content_9["levels"] as level>
    ${level.name}
    </#list>

     

    I get blank page. Without any errors or any content.

  • omygoodness's avatar
    omygoodness
    Mentor
    8 years ago

    Do you mean something like this?

    <#assign custom_content_9 = restadmin('/settings/name/customcontent.9_text').value />

    <#assign test = custom_content_9?eval>

     

    ${test}

     

    And how should I format JSON to be correct?

    For now my custom_content_9 looks exactly like this and ?eval didn't help:

    {
    "levels": [
    {
    "name": "LEVEL 1",
    "points": "0"
    },
    {
    "name": "LEVEL 2",
    "points": "10"
    }]
    }

     Error:

    FreeMarker template error (HTML_DEBUG mode; use RETHROW in production!)

    For "${...}" content: Expected a string or something automatically convertible to string (number, date or boolean), but this has evaluated to an extended_hash (wrapper: f.c.HashLiteral$SequenceHash):
    ==> test  [in template "ranking-test.ftl" at line 5, column 3]
    
    ----
    FTL stack trace ("~" means nesting-related):
    	- Failed at: ${test}  [in template "ranking-test.ftl" at line 5, column 1]

    SOLUTION 

    Ok. I think I have solution :) Custom content with JSON or rather array should look like this:

     

    {
        "name": "LEVEL1",
        "points": "0",
        "name": "LEVEL2",
        "points": "10",
        "name": "LEVEL3",
        "points": "50"
    }

    Then we have ?keys for keys in my case "name" and "points" and ?values for values like "LEVEL1" and number of points

     

    <#assign test = restadmin('/settings/name/customcontent.9_text').value?eval>
    
    <#list test?keys as k>
      ${k}
    </#list>
    
    <#list test?values as v>
      ${v}
    </#list>

    So in the end ?eval worked for me but proper format of data is crucial here.