I wanted to create window similar to 'Create Project' which is described in createRepo.soy template file. I created servlet which displays .soy file and at the begginin I wanted to just display copy of createRepo.soy. Servlet code looks like that:
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { final SoyFileSet sfs = new SoyFileSet.Builder().add(new File("src/main/resources/cloneRepo/createRepo.soy")).build(); final SoyTofu.Renderer renderer = sfs.compileToJavaObj().newRenderer("stash.page.createRepo"); resp.setContentType("text/html"); resp.getWriter().write(renderer.render()); }
Probably some parameters like project are mising, but that's not important for now. With this code I get errors like that:
[WARNING] [talledLocalContainer] SEVERE: Servlet.service() for servlet plugins threw exception
[WARNING] [talledLocalContainer] com.google.template.soy.base.SoySyntaxException: In file src/main/resources/cloneRepo/createRepo.soy:11: Unrecognized function 'webResourceManager_requireResourcesForContext' (function call "webResourceManager_requireResourcesForContext('internal.page.createRepo')").
Is it possible to somehow reuse this file without modifying it completley?
Or maybe my whole approach is wrong?
This is definitely possible but just as a note, you shouldn't consider our soy templates as a public API. We provide no guarantee that these templates won't change or that they work correctly from within a plugin.
That said, what you need to do is add the atlassian-soy-template-renderer-api as a provided dependency to your plugin
<dependency> <groupId>com.atlassian.soy</groupId> <artifactId>soy-template-renderer-api</artifactId> <version>1.1.1</version> <scope>provided</scope> </dependency>
You can then use the SoyTemplateRenderer to render the template. All templates are based off web resources for dependency resolution of files and custom functions. All of Stash's server side templates are currently available in the com.atlassian.stash.stash-web-plugin:server-soy-templates web resource module.
So for instance to render the createRepo page you can do the following:
soyTemplateRenderer.render(response.getWriter(), "com.atlassian.stash.stash-web-plugin:server-soy-templates", "stash.page.createRepo", new HashMap(), new HashMap());
Thanks for your help! I'm glat that it's possible at all :)
Unlucky when I tried to follow your suggestion I encountered some more problems.
First of all, from where in my servlet I should get soyTemplateRenderer? I looked at source code and found out that it's injected by spring and should be accesible as bean. So I did something like that:
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
SoyTemplateRenderer soyTemplateRenderer = (SoyTemplateRenderer) context.getBean(SoyTemplateRenderer.class);
Unlucky, this doesn't work as I expected:
[WARNING] [talledLocalContainer] SEVERE: Servlet.service() for servlet plugins threw exception
[WARNING] [talledLocalContainer] java.lang.IllegalStateException: Context attribute is not of type WebApplicationContext: Root WebApplicationContext: startup date [Mon Jul 09 18:15:02 CEST 2012]; root of context hierarchy
Can you tell me what am I doing wrong or at least point me to some resources where I could find answer myself?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Just use constructor injection and also include the SoyTemplateRenderer in a component-import in your atlassian-plugin.xml
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks Colin! Somehow I completely forgot about this possibility. Unlucky I have one more problem. I tried to add:
<component-import key="soyTemplateRenderer" interface="com.atlassian.soy.renderer.SoyTemplateRenderer" />
to my atlassian-plugin.xml but it seems to be not working properly. If I put this line right after plugin-info section then whole plugin seems to be no installed correctly (and it says that there is 0 modules at all).
I'm sure I'm missing something really simple, but I have no idea what it could be.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Was there an exception in the logs?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Somehow it works now. I guess I had one more subltle bug in atlassian-plugin.xml.
I guess I'm almost there. I have - hopefully - last guestion. My code currently looks like that:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final Project project = projectService.findByKey("PROJECT_1");
if (project != null) {
try {
soyTemplateRenderer.render(
resp.getWriter(),
"com.atlassian.stash.stash-web-plugin:server-soy-templates",
"stash.page.createRepo",
ImmutableMap.<String, Object>of(
"project", project
)
);
} catch (SoyException e) {
e.printStackTrace()
}
}
}
I need to pass project parameter to the template, but I don't know how it should look like. I only know that it must be able to work with this:
{{param contentTitle: cav_i18n('stash.web.repository.create.repository', 'Create a Repository in {0}', $project.name) /}}
and
{foreach $webPanel in getWebPanels('stash.web.repository.create.beforefields', [ 'project' : $project ])}
I tried to put as parameter something like that:
ImmutableMap.<String, Object>of(
"project", project,
"project.name", project.getName()
)
but then I get:
[WARNING] [talledLocalContainer] com.google.template.soy.tofu.SoyTofuException: In template stash.page.createRepo: When evaluating "getWebPanels('stash.web.repository.create.beforefields', $ij.request, ['project': $project])": Error while computing function "getWebPanels('stash.web.repository.create.beforefields', $ij.request, ['project': $project])": Non-string found when expecting string value.
And for parameter like:
ImmutableMap.<String, Object>of(
"project", project.getKey(),
"project.name", project.getName()
)
I'm getting:
WARNING] [talledLocalContainer] com.google.template.soy.data.SoyDataException: Failed to evaluate key string "project.name" for put().
I tried few different variants but without success so far...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I wanted to try something simplier, so I replaced "stash.page.createRepo" with "stash.page.createProject" which does not require any parameters. Unlucky it still generates errors:
[WARNING] [talledLocalContainer] com.google.template.soy.tofu.SoyTofuException: In template stash.page.createProject: When evaluating "getWebPanels('stash.web.project.create.beforefields', $ij.request)": Error while computing function "getWebPanels('stash.web.project.create.beforefields', $ij.request)": Non-string found when expecting string value.
But this mean it's not related to missing parameter, but rather to some not loaded component or whatever else. Do you have any idea what could be the reason guys?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Ok, I got it now. Couple of parameters were missing, but that's it.
To check what is required it's worth to look at SoyView, InjectedDataFactory and SoyResponseBuilder (which unlucky are internal ones, so I had to rewrite part of their functionality).
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.