grails current page highlight - grails

In grails I have a menu. I'm trying to highlight the menu item for the active page:
link1
link2 (show as bold if the controller action partially matches this gsp name)
link3
I have working code but it seems like there would be a better way.
Taglib works fine:
def active = { attrs, body ->
for (page in attrs.check) {
if (params.action.startsWith(page)) {
out << "current"
break
}
}
}
This option works fine, but seems wordy:
<li>Contact Info</li>
<li>About You</li>
This blows up:
<g:link action='myProfile' class="${<xyz:active check='${['myControllerAction']}'/>}">My Profile</g:link>
I don't believe you can pass a taglib as a parameter to g:link
I also have the requirement that multiple gsps/actions would cause a link to be active because of how they are named:
aboutYouLocation
aboutYouBackground
aboutYouEducation
all make this link the active one:
About You
I can do a partial match, but I've also got some actions/gsps that begin with aboutYour (extra R) resulting in my use of the array being passed into my taglib.

There's a standard way of doing that with the Platform Core plugin. It will provide you a Navigation API:
grails-app/conf/AppNavigation.groovy
navigation = {
// Declare the "app" scope, used by default in tags
app {
contact(action: 'contactInfo')
about(action: 'aboutYouFamily')
}
}
*grails-app/view/_menu.gsp* (template that you can use in your layout or GSP's)
<nav:menu scope="app" id="navigation" />
You can also customize the html generated for your menu, check the custom item rendering.

Related

Mapping URL in main menu to every page

I am using in my grails 2.3.4 project with spring security and spring securit ui.
I am having scaffolde my domain contact to the view. I have also a .gsp page which is not scarfolded.
My links from my main menue looks like that:
<li>Pricing</li>
<li>Contact</li>
Thats my URLMappings
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?(.${format})?"{
constraints {
// apply constraints here
}
}
"/private/$controller/$action?/$id?(.${format})?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"/pricing"(view:"/pricing")
"/private/dashboard"(view:"/private/dashboard")
"/contact/create"(view:"/contact/create")
"500"(view:'/error')
}
}
My problem is when I am using this two links from my mainpage / then everythings works fine. However using them from 5432:localhost/TestApp/pricing I am getting the link 5432:localhost/TestApp/pricing/contact/create
which goes is not available. If I am using <li>Contact</li>, I am going to 5432:localhost/contact/create, which is also not available. How to go to contact/create from every page?
I appreciate your reply!
The simplest and safest approach would be
<li><g:link uri="/contact/create">Contact</g:link></li>
Other attributes on the g:link tag will pass through to the generated a tag, with the exception of id - you need to use elementId instead, as id is treated as a parameter to the link generation (controller/action/id)
<li><g:link uri="/contact/create" class="nav" elementId="contactlink">Contact</g:link></li>
would become
<li>Contact</li>
(where /TestApp is the application context path - if you deploy the app at a different context path then then link will change to match).

How to remove a-tag's title param in tt_news using typoscript

The standard output of a tt_news list view hyperlink is like:
News Headline
How to remove the title tag from the standard output with typoscript ? So that you get:
News Headline
I' am looking for a typoscript something like:
plugin.tt_news.displayList.linkParams.ATagParams >
Info: The template (sub)marker which includes the hyperlink is called:
<!-- ###LINK_ITEM### -->
... some Headline ...
<!-- ###LINK_ITEM### -->
There is a hook for this.
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['tt_news']['getSingleViewLinkHook']
You will have to use it in an own extension.
Your hook consuming class will have to implement the following method
function processSingleViewLink(&$linkWrap, $url, &$params, &$pObj) {
// modify $linkWrap to remove title="" using regex
[...]
}
See here for reference how to consume hooks in TYPO3: http://typo3.org/documentation/article/how-to-use-existing-hooks-in-your-own-extension/
It's
plugin.tt_news.displayList.linkTitleField =
However title will be there, it will not be filled.
If you want to remove the empty title part as well you need to dive into the plugin to remove it.

Display Media Library Picker Field image in a lists alternate item view in Orchard CMS

So the title pretty much says it all.
I am using Orchard CMS v1.7. I have created my own content type (Product Categories) - this is essentially the same as a page though also has an extra field (Media Library Picker Field) to allow me to select and display a single image - this will be displayed on both the list item view and also the main page content.
I use a projection page to display all content types "ProductCategories". This works well and as expected.
I now want to display this additional image within each of the items in the list of ProductCategories when viewing the projection page.
Using Shape Tracing I created an alternate for my list items.
By default, this looks like this:
#using Orchard.Utility.Extensions;
#{
if (Model.Title != null) {
Layout.Title = Model.Title;
}
Model.Classes.Add("content-item");
var contentTypeClassName = ((string)Model.ContentItem.ContentType).HtmlClassify();
Model.Classes.Add(contentTypeClassName);
var tag = Tag(Model, "article");
}
#tag.StartElement
<header>
#Display(Model.Header)
#if (Model.Meta != null) {
<div class="metadata">
#Display(Model.Meta)
</div>
}
</header>
#Display(Model.Content)
#if(Model.Footer != null) {
<footer>
#Display(Model.Footer)
</footer>
}
#tag.EndElement
I am now stuck - I have no idea how I display the image that is associated to this item.
I step through my code to inspect the content of the Model passed into my custom list item view and something strange happens...
when the model is loaded in there is no ListLogo inside. - see first snapshot..
However, the moment i step through #if (Model.Meta != null) my ListLogo can now be found on the object, however it's still empty - as in this snapshot.
How do I display the image associated to this content item - there is only 1 too.
Do I need to override creation of the actual list itself? If so, can you give me pointers?
Thanks in advance.
bah - so once again this all comes down to the Placement.info file in my theme.
I added a reference to the Fields_MediaLibraryPicker inside my DisplayType="Summary" and it worked like a charm.
E.G My placement.info in my theme has this for an item in my list
<Match DisplayType="Summary">
<Place Parts_Common_Metadata_Summary="-"/>
<Place Parts_Title="-"/>
<Place Fields_MediaLibraryPicker="Content:1" /> <!-- this adds the field.. -->
</Match>

Multilingual in grails view

i'm working in Multilingual grails application (English and arbaic) , i want when the user chooses Arabic language the view's labels will be on the right side of the page and in English on the left side , how this can be achieved ?
thanks
You can use internationalization in grails through messages.properties file, you can define message signature in files and and they can be accessed through ?lang=es on the URL, you may need to have two files one for english and another for Arabic.
for example define in the messages.properties:
vendor.link.dashboardLink = Vendor Dashboard
and on the GSP page you can access it like:
<g:message code="vendor.link.dashboardLink" />
you can find more about internalization at grails doc have a look at http://grails.org/doc/2.2.1/guide/i18n.html
If the views have differences beyond simple string substitution, I would recommend using a different set of views based on locale:
Example controller code:
import org.springframework.web.servlet.support.RequestContextUtils as RCU
class ExampleController {
final static String englishLanguageCode = new Locale('en').getLanguage()
final static String arabicLanguageCode = new Locale('ar').getLanguage()
def differentViews() {
def currentLocale = RCU.getLocale(request)
switch(currentLocale.language) {
case englishLanguageCode:
render view: 'englishView'
break
case arabicLanguageCode:
render view: 'arabicView'
break
default:
// pick a default view or error page, etc.
}
}
}

Grails grailApplication.controllerClasses sort controller by package

I have the following code that grabs all controllers, sorts it, and outputs in li tags:
<g:each var="c" in="${grailsApplication.controllerClasses.sort { it.fullName } }">
<li<%= c.logicalPropertyName == controllerName ? ' class="active"' : '' %>>
<g:link controller="${c.logicalPropertyName}">${c.naturalName}</g:link>
</li>
</g:each>
I have a need to filter out controllers by package i.e. grab controller from a certain package.
For example:
com.app.module.mars.controller.HelloController
com.app.module.venus.controller.PrintController
As you can see I'm packaging controllers by modules, so mars will have its own set of controllers and venus will have its own. Then in the UI I want to use the above code (with some filter) which will show modules as main-menus and their controllers as dropdowns.
How can I apply such a filter? Or if you could guide me in the right direction would be great. Thanks.
You can use GrailsClassUtils.isClassBelowPackage() which takes a class and a list of packages as the arguments. So this should do the trick:
GrailsClassUtils.isClassBelowPackage(c.class, ['com.app.module.mars'])
Edit: grailsApplication.controllerClasses probably gives you a list of GrailsClass objects, so you'd want to use c.clazz instead of c.class like
grailsApplication.controllerClasses.each { c ->
GrailsClassUtils.isClassBelowPackage(c.clazz, ['com.app.module.mars'])
}
You can use Collection#groupBy to group the controller classes by package name.
I don't have a Grails system to make a quick test right now, but this would be a little example of grouping classes by package name:
def classes = [Integer, List, String]
def classesByPackage = classes.groupBy { it.package.name }
assert classesByPackage == ['java.lang': [Integer, String], 'java.util': [List]]
You can then iterate through each packageName to make each menu and through each class under that package name to make each menu item. Something like...
classesByPackage.each { packageName, packageClasses ->
println "Menu $packageName"
packageClasses.each { println " Item $it.simpleName" }
}
... but with GSP-style loops :)

Resources