1

I'm refactoring scaffolding templates and I hit a wall with this issue:

I was trying to call service (some security logic) from template _FORM.GSP - but in the code part, not in the output part

I've read and tried what was suggested in here: How do I call a Grails service from a gsp?

  1. I've tried to use taglib, but my knowledge of grails may not be extensive enough for that
  2. I've tried add import and def to the beginning of _FORM.GSP file (both grailsApplication and application instantiation of service were crashing on missing property application resp. missing property grailsApplication)
  3. I've even tried to call the taglib from the code both directly as method isAllowedToEdit and also as g.isAllowedToEdit both crashing on unknown method resp. "no such property g"

it seems that template _form.gsp has different rules than standard gsp view

I want to do something like this:

private renderFieldForProperty(p, owningClass, prefix = "") {
    boolean hasHibernate = pluginManager?.hasGrailsPlugin('hibernate')
    boolean display = true
    boolean required = false
    if (hasHibernate) {
        cp = owningClass.constrainedProperties[p.name]
        display = (cp ? cp.display : true)
        required = (cp ? !(cp.propertyType in [boolean, Boolean]) && !cp.nullable && (cp.propertyType != String || !cp.blank) : false)
    }

    /* trying to do this part */
    // I want to assign value to cp.editable - so later I can render read-only fields in renderEdit
    if (!mySecurityService.canEdit(springSecurityService.currentUser, owningClass.getClass(), actionName, p.name)) {
        cp.editable = false
    }
    /* trying to do this part */

    if (display) { %>
<div class="fieldcontain \${hasErrors(bean: ${propertyName}, field: '${prefix}${p.name}', 'error')} ${required ? 'required' : ''}">
    <label for="${prefix}${p.name}">
        <g:message code="${domainClass.propertyName}.${prefix}${p.name}.label" default="${p.naturalName}" />
        <% if (required) { %><span class="required-indicator">*</span><% } %>
    </label>
    ${renderEditor(p)}
</div>
<%  }   } %>

if there is any way to assign cp.editable - I'll try your suggestions

Community
  • 1
  • 1
hoppo
  • 13
  • 2

2 Answers2

1

it seems that template _form.gsp has different rules than standard gsp view

The generated _form.gsp works same as other gsps but the template inside the scr/templates/scaffolding/ is different. Customizing the templates like you are doing is a bit more tricky. Keep in mind that the logic you are writing is for Grails on how to generate views(gsp). Meaning you are telling Grails to check some logic before generating the views in memory or in the file. You might be able to accomplish that to some extend for dynamic (in memory) scaffolding at run-time but for sure not for static scaffolding. That's because Grails is not aware of currentUser when generating the templates.

Your problem will be much simpler if you generate your views and then customize them instead of modifying their templates. Then you can inject your services and do other checks. However, as you also mentioned those logics are better off in a tag library here.

Also since you mentioned security, rendering a field non-editable does not guaranty inability to edit your fields. I would suggest to put the check logic inside your controller for example in SAVE or UPDATE action to prevent any unauthorized user editing fields.

Alidad
  • 5,463
  • 1
  • 24
  • 47
  • 1
    yeah, I was afraid it will be something like this - that (scaffolding) template for (rendering) template may be out of standard contexts of views and (rendering) temlpates; So as I see it, the only way to use dynamic (session) logic inside these is to use taglibs which will evaluate "online" depending on current user roles; I'll try it and when it works I'll rate your answer - it was eyeopening (sadly...) – hoppo Jun 18 '13 at 04:55
0

Did you try this?

    <%@ page import="com.myproject.MyService" %>
<%
    def myService = grailsApplication.classLoader.loadClass('com.myproject.MyService').newInstance()
%>

this will work for sure.

go through this link : click here

sanghavi7
  • 758
  • 1
  • 15
  • 38
  • I am working in template GSPs, not standard views so this won't compile through the template generator -> "Failed to parse template scrip" and it failed on @ sign parsing – hoppo Jun 17 '13 at 06:44