Need to implement a page with search call from api and wrapping everything in an Umbraco Package.
Hello everyone,
I'm very new to Umbraco and to this forum. I wonder if you can help me out.
Requirement: Basically, we have an existing site using Umbraco 8. I have a task to implement a simple page that does searching/filtering of an external data set and display the results in a grid/table. Now these results are coming from an api call.
One of the challenges is that the V.S. solution file is no longer available. Past updates for this site were mostly content or UI related and thus they only needed to adjust the view templates which can be done in Umbraco admin. But now they need more functionalities.
Because of the mentioned limitation, it was suggested to explore the option of using umbraco packages for this kind of extension.
Now I have started some reading on how to build and implement the Property Editor (from Mr. Paul Seal) but I'm not sure how to tie this up to the requirement I have above. And most packages I have seen so far, (though I haven't checked a lot), are updates on the admin side of umbraco and not a something that would appear in the content (there's a good chance that I'm just missing something).
I don't think you need a package for your requirement, so would ignore that.
You should be able to do everything you need in a View (an Umbraco template). The question you need to ask yourself is whether you want to do it server side (c#) or client side (JavaScript).
Assuming you want to do it server side, then you can write arbitrary C# in a razor view. It won't be pretty, because obviously it's not best practice to put your code and logic in a view, but if you can't create a Controller then you don't have much choice. Note you can create both functions and helpers in a razor view - see https://www.mikesdotnetting.com/article/173/the-difference-between-helpers-and-functions-in-webmatrix
If you want to do it client side, then there are many ways to do that, from pure JS to using jQuery to using View.js, Angular etc. You can put the logic in script files then.
Thank you Dan and sorry for the really late response. I got stuck with other project. Anyway I have explored the client side route as the deploy team is really pushing back on adding more dlls to this project.
Although upon studying how the package works it seems I can add compiled libraries as part of the deploy. I will try to explore that solution too.
I guess bottom line my inquiry has 2 unrelated features:
1.) Search call from an API - I figured this out and I actually have 2 solutions now: one using pure ajax call and another using surface controllers. I have decided to use the ajax call for now so I can do it on the .cshtml directly,
2.a) How to put all this in a package - Yeah I was required to pursue the packaging route as it will help ease with the deployments. Still studying this bit. I'm actually struggling to understand how to read the data type property prevalues (config values) and have them pass to the razor page for processing. For now the configs are there but actually not being used anywhere.
2.b) Ultimately, the main heart of my package is that partial view (mainView.cshtml) that has that search api function from requirement 1. To hook it up to any page I simply call it from a main template (e.g. Contact.cshtml):
However, this loads even if I don't add the datatype in the content. How do I make so it will only be called when user adds the datatype in content? If user removed the datatype from content, this partial should not be loaded too.
I don't know if you go full ajax is the best solution. If the API has any kind of auth with secret keys I suggest to use a controller to call the API.
Could you please be more specific about the document type/template you want to render this search?
Do you have a generic document type to create pages? Do you use content blocks to render components to the pages?
If you use content blocks then it would be even easier to make it a package.
The custom property editor what properties do you want to have? And do you really need one? I mean you could have some true-false properties in a composition (so you can add this to any doctype) and based on that you could render the partial in the template.
So your package could have a document type of "API Search Settings" (lets say that this doctype has a true-false property with alias "renderSearch"), your partial view, and the dll of the project you use to create the package.(The dll should contain your controller to call the API, I think you should create a class library project for the controller so the dll will contain only that).
Then in your main project after you install the package you could add as composition the doctype "API Search Settings" to the doctype you want to render the partial.
Then inside your template you could do that
if (Model.Value<bool>("renderSearch") == true){
@Html.Partial("~/Views/Partials/MyPackage/mainView.cshtml")
}
Btw working without solution would be hard for development, recently I had a task to migrate a site from Umbraco cloud to Azure and it had only the .Web project (which means no one ever create a solution for this project, like yours)
What I did was to create a new solution and install the same version of Umbraco as the project from U Cloud and copy all the files there (App_Plugins, Views, Media, etc).
Then I inspect the dlls and install any packages that was missing (again same version with the original one). Check the settings in the web config, connect the DB and that was it! I had a solution for my project!
If you want to try it I could help you more.
Thank you for the detailed response. I actually tried you suggestion and it worked. It simplified my need which helped me understand it better. As you suggested, I simply added a doctype toggle for a true false value and assigned it an alias ("myToggle") and easily enough, the view was able to understand the true-false value. So if the value is true, my cshtml is loaded vice versa. Moreover if "myToggle" is not added to the page, the cshtml won't load as well which is my expected result. Though this is not exactly the solution I was looking for, I think this will work for now.
Now, what I'm looking for is a doctype that has multiple properties that you can use. I'm hoping this will contain the values for APIKey, Page Size, default labels etc. So naturally I had to study on how to make property editors and register them: https://our.umbraco.com/documentation/Tutorials/creating-a-property-editor/
I think what I needed is in the page 2 (https://our.umbraco.com/documentation/Tutorials/creating-a-property-editor/part-2). This talks about adding property configuration (i think they also call it prevalues). Much like in the gmaps package, infos like api key, default theme, default coordinates etc... are all saved here. Now this tutorial talks about how to create them but I don't understand how to use them. I just need to know how to access these values from a view or controller or anything that ultimately can be passed to my mainView.cshtml. Once I learn this I can also put the toggle on off here.
Regarding the V.S. solution I will try what you suggested too. It's really tricky to extend without it. That's actually why this package idea was suggested to me in the first place...
Do you actually need a custom property editor? If you just want to have properties containing things like an API key, URL etc. you can just create a multiple normal properties using (say) a text string. Then these would be easy to access.
If you really want to go the route of using a custom property editor then you'd probably be storing your values as a JSON object. To access it you will need to convert it back to a model. Normally in Umbraco you'd use a custom value converter to do this. It takes the JSON stored in the editor and converts it to a C# object.
You could create a custom property editor to do that but you are going the wrong direction. The prevalues are accessible from your editor it self. Its like you are creating some configuration/settings for the editor. Based on that settings the user will have different experience when he is using your property editor.
In you code your can access only the saved model value (from your js code $scope.model.value (If I am not wrong that's the syntax))
2 Faults here.
The user-editor of your site should have access to the content section, he shouldn't mess up with the settings section. The settings section is for the devs only.
If you store the api key (which should be secret) in the property editor or in your "contact" node, this means that if someone else wants to reuse your search in a another page he needs to add again all of the settings including the api keys
Best option to store the keys is in your web config in the app settings
var myKey= ConfigurationManager.AppSettings["MyApiKey"]
Also if you want to store these settings of the api somewhere to be editable then create a node where you store global settings like this one. (without template)
Then store the other settings like "number of pages" (settings that you want the editors to change based on the page they want to display the search) in the node that will render the search in our case the "contact".
Best think and easiest to do is what Dan said, store your values to textstrings and numeric properties and get the values like you did with the true-false property
I think I would go with the composition route and assign my configs to textboxes. I just tested this and found out that the composition can be part of the package so this will work plus it's way simpler to access the values.
I appreciate you guys pointing me to the right direction. There is no particular reason why I wanted the property converter. I just saw that's how it was done on the Gmaps package so I thought that's the way I should go too.
Need to implement a page with search call from api and wrapping everything in an Umbraco Package.
Hello everyone,
I'm very new to Umbraco and to this forum. I wonder if you can help me out.
Requirement: Basically, we have an existing site using Umbraco 8. I have a task to implement a simple page that does searching/filtering of an external data set and display the results in a grid/table. Now these results are coming from an api call.
One of the challenges is that the V.S. solution file is no longer available. Past updates for this site were mostly content or UI related and thus they only needed to adjust the view templates which can be done in Umbraco admin. But now they need more functionalities.
Because of the mentioned limitation, it was suggested to explore the option of using umbraco packages for this kind of extension. Now I have started some reading on how to build and implement the Property Editor (from Mr. Paul Seal) but I'm not sure how to tie this up to the requirement I have above. And most packages I have seen so far, (though I haven't checked a lot), are updates on the admin side of umbraco and not a something that would appear in the content (there's a good chance that I'm just missing something).
Any help would be appreciated. Thank you.
I don't think you need a package for your requirement, so would ignore that.
You should be able to do everything you need in a View (an Umbraco template). The question you need to ask yourself is whether you want to do it server side (c#) or client side (JavaScript).
Assuming you want to do it server side, then you can write arbitrary C# in a razor view. It won't be pretty, because obviously it's not best practice to put your code and logic in a view, but if you can't create a Controller then you don't have much choice. Note you can create both functions and helpers in a razor view - see https://www.mikesdotnetting.com/article/173/the-difference-between-helpers-and-functions-in-webmatrix
If you want to do it client side, then there are many ways to do that, from pure JS to using jQuery to using View.js, Angular etc. You can put the logic in script files then.
Thank you Dan and sorry for the really late response. I got stuck with other project. Anyway I have explored the client side route as the deploy team is really pushing back on adding more dlls to this project.
Although upon studying how the package works it seems I can add compiled libraries as part of the deploy. I will try to explore that solution too.
I guess bottom line my inquiry has 2 unrelated features:
1.) Search call from an API - I figured this out and I actually have 2 solutions now: one using pure ajax call and another using surface controllers. I have decided to use the ajax call for now so I can do it on the .cshtml directly,
2.a) How to put all this in a package - Yeah I was required to pursue the packaging route as it will help ease with the deployments. Still studying this bit. I'm actually struggling to understand how to read the data type property prevalues (config values) and have them pass to the razor page for processing. For now the configs are there but actually not being used anywhere.
2.b) Ultimately, the main heart of my package is that partial view (mainView.cshtml) that has that search api function from requirement 1. To hook it up to any page I simply call it from a main template (e.g. Contact.cshtml):
@Html.Partial("~/Views/Partials/MyPackage/mainView.cshtml")
However, this loads even if I don't add the datatype in the content. How do I make so it will only be called when user adds the datatype in content? If user removed the datatype from content, this partial should not be loaded too.
Thanks in advance.
Hi Kiko,
I don't know if you go full ajax is the best solution. If the API has any kind of auth with secret keys I suggest to use a controller to call the API.
Could you please be more specific about the document type/template you want to render this search? Do you have a generic document type to create pages? Do you use content blocks to render components to the pages?
If you use content blocks then it would be even easier to make it a package.
The custom property editor what properties do you want to have? And do you really need one? I mean you could have some true-false properties in a composition (so you can add this to any doctype) and based on that you could render the partial in the template.
So your package could have a document type of "API Search Settings" (lets say that this doctype has a true-false property with alias "renderSearch"), your partial view, and the dll of the project you use to create the package.(The dll should contain your controller to call the API, I think you should create a class library project for the controller so the dll will contain only that).
Then in your main project after you install the package you could add as composition the doctype "API Search Settings" to the doctype you want to render the partial. Then inside your template you could do that
Btw working without solution would be hard for development, recently I had a task to migrate a site from Umbraco cloud to Azure and it had only the .Web project (which means no one ever create a solution for this project, like yours)
What I did was to create a new solution and install the same version of Umbraco as the project from U Cloud and copy all the files there (App_Plugins, Views, Media, etc). Then I inspect the dlls and install any packages that was missing (again same version with the original one). Check the settings in the web config, connect the DB and that was it! I had a solution for my project! If you want to try it I could help you more.
Thanks, T
Hi Thomas,
Thank you for the detailed response. I actually tried you suggestion and it worked. It simplified my need which helped me understand it better. As you suggested, I simply added a doctype toggle for a true false value and assigned it an alias ("myToggle") and easily enough, the view was able to understand the true-false value. So if the value is true, my cshtml is loaded vice versa. Moreover if "myToggle" is not added to the page, the cshtml won't load as well which is my expected result. Though this is not exactly the solution I was looking for, I think this will work for now.
Now, what I'm looking for is a doctype that has multiple properties that you can use. I'm hoping this will contain the values for APIKey, Page Size, default labels etc. So naturally I had to study on how to make property editors and register them: https://our.umbraco.com/documentation/Tutorials/creating-a-property-editor/
I think what I needed is in the page 2 (https://our.umbraco.com/documentation/Tutorials/creating-a-property-editor/part-2). This talks about adding property configuration (i think they also call it prevalues). Much like in the gmaps package, infos like api key, default theme, default coordinates etc... are all saved here. Now this tutorial talks about how to create them but I don't understand how to use them. I just need to know how to access these values from a view or controller or anything that ultimately can be passed to my mainView.cshtml. Once I learn this I can also put the toggle on off here.
Regarding the V.S. solution I will try what you suggested too. It's really tricky to extend without it. That's actually why this package idea was suggested to me in the first place...
Thank you again.
Do you actually need a custom property editor? If you just want to have properties containing things like an API key, URL etc. you can just create a multiple normal properties using (say) a text string. Then these would be easy to access.
If you really want to go the route of using a custom property editor then you'd probably be storing your values as a JSON object. To access it you will need to convert it back to a model. Normally in Umbraco you'd use a custom value converter to do this. It takes the JSON stored in the editor and converts it to a C# object.
https://our.umbraco.com/Documentation/Extending/Property-Editors/value-converters
Hi Kiko,
You could create a custom property editor to do that but you are going the wrong direction. The prevalues are accessible from your editor it self. Its like you are creating some configuration/settings for the editor. Based on that settings the user will have different experience when he is using your property editor.
In you code your can access only the saved model value (from your js code $scope.model.value (If I am not wrong that's the syntax))
2 Faults here.
The user-editor of your site should have access to the content section, he shouldn't mess up with the settings section. The settings section is for the devs only.
If you store the api key (which should be secret) in the property editor or in your "contact" node, this means that if someone else wants to reuse your search in a another page he needs to add again all of the settings including the api keys
Best option to store the keys is in your web config in the app settings
you can access them from anywhere with this code.
Also if you want to store these settings of the api somewhere to be editable then create a node where you store global settings like this one. (without template)
Then store the other settings like "number of pages" (settings that you want the editors to change based on the page they want to display the search) in the node that will render the search in our case the "contact".
You could use the compositions I mentioned yesterday. https://umbraco.tv/videos/umbraco-v7/implementor/fundamentals/document-types/folders-and-compositions/ (same thing in V8)
Best think and easiest to do is what Dan said, store your values to textstrings and numeric properties and get the values like you did with the true-false property
In sort I don't think you need a custom editor
Thank you Dan. Thank you Thomas,
I think I would go with the composition route and assign my configs to textboxes. I just tested this and found out that the composition can be part of the package so this will work plus it's way simpler to access the values.
I appreciate you guys pointing me to the right direction. There is no particular reason why I wanted the property converter. I just saw that's how it was done on the Gmaps package so I thought that's the way I should go too.
I'll let you guys know if there's anything else.
is working on a reply...