I need an explanation about how to use Grails (with different controllers) - grails

I'm trying to create a little and basical Twitter-like site with Grails.
Here is the main part of my project arborescence (UserCwitter handles users, MessageCwitter handles messages and GroupCwitter handles groups like followers/followings) :
I'm trying to insert a text field to write a new message in the index (here it's index_final.gsp).
So I added this piece of code (in every controller my function to create a new user/message/groupe is called save()) :
<g:form action="save">
<fieldset class="form">
<g:render template="form"/>
</fieldset>
</g:form>
But I don't know why, the form that appears is the one to create a new user and not a message.
Why and what should I do ?
Thanks for your help. Sorry if this is something really easy or even stupid, I'm really new to Grails.

From render tag documentation, related to template attribute:
Note that if the value of the template attribute starts with a '/' it
will be resolved relative to the views directory. This is useful for
sharing templates between views. Without the leading '/' it will be
first be resolved relative to the current controller's view directory
then, failing that, the top level views directory.
So you should use
<g:render template="/messageCwitter/form"/>
if you want to render form template that is in messageCwitter folder.

Related

How to load a partial view from ASP.NET MVC application root into area view?

I have an area in my ASP.NET MVC application that needs to make use of partial views stored in the main application.
The code in question is being migrated from the main application into an area for organization, so I need to update the helper tags for the partial views.
Currently my tags look like this:
#await Html.PartialAsync("../Shared/Partials/_details.cshtml")
Of course, this fails in an area, since this helper only begins searching at the Areas/MyArea/ folder. I've tried adding additional ../ to the beginning of the address, but that doesn't change anything. How can I reconnect my partial views to this area?
You need to reference the app root.
The following example references a partial view from the app root. Paths that start with a tilde-slash (~/) or a slash (/) refer to the app root:
Partial Tag Helper:
<partial name="~/Pages/Folder/_PartialName.cshtml" />
<partial name="/Pages/Folder/_PartialName.cshtml" />
Asynchronous HTML Helper:
#await Html.PartialAsync("~/Pages/Folder/_PartialName.cshtml")
#await Html.PartialAsync("/Pages/Folder/_PartialName.cshtml")
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-6.0
See also: significance of tilde sign

Direct BeginUmbracoForm action to another page

I am trying to set up a global search box that posts to a search page in umbraco 7. This template uses a shared partial containing Html.BeginUmbracoForm() that points to a SurfaceController.
Since this is a global control, I want the form to be posted to the /search page instead of the current page. BeginUmbracoForm only seems to be able to post to the current page unless I'm mistaken.
I want something like RedirectToUmbracoPage(id), but clears this post values on redirect.
Is there a way to get an ActionResult like CurrentUmbracoPage which keeps the post values?
I would not try using surfacecontrollers for that purpose. Surfacecontrollers are auto routed. They are created to (e.g.) make #Html.Action(...) work on every umbraco page. Including postbacks on these actions or macros.
If you only need a "redirect" to the /search page, you don't need a surface controller. A simple partial will do the job.
<form action="/search" method="get">
Search <input type="search" name="q" />
</form>
Of course you can replace the url using some Umbraco logic like #Umbraco.TypedContentSingleAtXPath("//Search") or other Umbraco magic.
In the umbraco documentation project is an example where Html.Action is used.

Using one views gsp in another views gsp

So my question is, hopefully, very simple.
I have two different domains with corresponding controllers/view folders etc.
I want to call the second _form.gsp from the first _form.gsp (within a g:each as there will be multiple things to display) and pass in the relevant data for the second _form.gsp to render from, how do I do that?
I know I can use g:render template = "myotherForm" but I don't know how to point it to another view folder or how to pass in the details...
Thanks in advance and let me know if more information is required...
You can Refer this
Grails uses the convention of placing underscore before the name of a view to identify it as a template.
Example grails-app/views/book/_bookTemplate.gsp:
<div class="book" id="${book?.id}">
<div>Title: ${book?.title}</div>
<div>Author: ${book?.author?.name}</div>
</div>
Then use render tag
<g:render template="bookTemplate" model="[book: myBook]" />
You're right, <g:render is the right tool. By default, for template="myOtherTempalte" it looks for tempalte in current directory, but you could pass full path, if it's from another controller. Like template="/forms/myOtherTemplate". And use model="" to pass parameters, same as inside controller:
<g:each in="${things}" var="x">
<g:render template="/forms/myOtherTemplate" model="${thing: x}"/>
</g:each>

I can't get the grails controller "render" method to work with an explicit template

I'm just getting started with grails, and I'm having an issue.
I have a "controller" and "view" for the projects home page (there's no model for the home page)
I called the view "index.gsp", and put it in a directory views/home
However, no matter what I do, grails is trying to read the page "home.gsp" (and then home.jsp), despite me having explicitly specified the index with the "template" attribute in the render call.
class HomeController {
String someparameter = "xyzzy"
def index = {
render(view:"home", template:"index") // I also tried "index.gsp" and "home/index.gsp"
}
}
I think I may be using the "template" attribute wrong, because I only see it used in examples for view-less template rendering. However the documentation gives no such limitation.
Is there any way to explicitly specify the name of a template? I just caved in and renamed it "home.gsp", but I'd like to understand what's going wrong.
(The home page in this application has no "model". Grails will use the controller has the model. In this example, you can access "someparameter" in the gsp template as ${someparameter}.)
I think you may be misunderstanding what a Grails template is. Think of a template as a reusable fragment. A template is a GSP that starts with an underscore like _menu.gsp that you would typically render from within another GSP with the a tag like <g:render template="menu"/>.
It doesn't make sense to render both a view and a template at the same time. They are mutually exclusive at this point.
Are you looking to implement a Layout? If so, see the docs or the grails.org explaination.
Basically, your view you would have a <meta name="layout" content="main"> tag in the <head/> tag of your view -- which indicates that the view will be meshed together with the main layout located in grails-app/views/layouts/main.gsp

Using HTML forms in ASP.NET MVC?

It seems like everything I look up on this subject has either changed since the release or is wildly different from eachother.
I just want to create a simple form in my view.
Should I be using the Html.BeginForm()/TextBox()/EndForm() methods or should I be using a plain-jane HTML form? Which is preferred?
This is what I have so far:
<%=Html.BeginForm("Create", "Product", FormMethod.Post); %>
<%=Html.TextBox("productTextBox", "Enter a shoe name"); %>
<input type="submit" name="createButton" value="Create Me!" />
<%=Html.EndForm(); %>
What is the "correct" way to create a simple form with a button and textbox in ASP.NET MVC and allow me to submit the data in the form to the /Product/Create action?
How do I then access the form data from within that method? Some people seem to use a "FormCollection" and others just do a Request.Form method. Which way should I use?
Can someone enlighten me?
The Form helpers are the recommended way because it allows you to provide a controller, action and other route data and the URL is auto-generated based on your routes (in Global.asax). The advantage is, if you decide to change your routes, you don't have to update every URL in your site.
The only reason I'd use an actual "<form>" tag was if I needed extra control over the markup that I couldn't get from Html.Form (I can't think of an example right now). Even if you choose to do that, you should use the "Url.Action" helper to get a URL from routing data. For example:
<form action="<%= Url.Action("Create") %>">
As for your second question, I'd suggest using the Model Binder. Check out ScottGu's Blog for some details on this.
Have a look at Link.
It's German text but the code should be understandable.
Have you looked at this:
http://weblogs.asp.net/scottgu/archive/2009/03/10/free-asp-net-mvc-ebook-tutorial.aspx
It's from the horse's mouth, and is up-to-date with the final release.

Resources