How can I best implement something like shortcodes (thats what it's called in Wordpress) in Grails.
I have a Grails application where the user can input text. This text is saved in the Database. The Text should contain something like "shortcodes":
class Page(){
String text = "please display [form A] above here."
}
In my view I display the value text from my domain Object.
${domainObject.text}
eg: "[form A]" should display a referenced Form A in the position where it was put in the text.
What's the best way I can do this in Grails.
Best approach is to use SimpleTemplateEngine. Using this you could have standard ${} block to specify variables.
Use method like below:
String renderTemplate(Reader template, Map bindings) {
try {
def engine = new groovy.text.SimpleTemplateEngine()
return engine.createTemplate(template).make(bindings)
} catch (MissingPropertyException mpe) {
log.error("Missing property in template binding", mpe)
}
return ""
}
Example:
String text = "please display ${formA} above here."
String parsedText = renderTemplate(new StringReader(text),[formA:'http://www.yourlink.com'])
Hope it helps!!
Related
I have a customer form having phone number fields like CountryCode, AreaCode and PhoneNumber. I would like to write a custom validation for these 3 fields where all of them can either remain empty (they are optional) or all of them can remain filled (no field can be left empty if one or two are filled).
Am trying to write a custom validation for this situation, however, am not clear how to do it. Please help.
It's unclear exactly what you're looking for here. If you're just struggling with the boolean logic, all you need is:
if (!String.IsNullOrWhiteSpace(model.CountryCode) ||
!String.IsNullOrWhiteSpace(model.AreaCode) ||
!String.IsNullOrWhiteSpace(model.PhoneNumber))
{
if (String.IsNullOrWhiteSpace(model.CountryCode)
{
ModelState.AddModelError(nameof(model.CountryCode), "Country code is required.");
}
if (String.IsNullOrWhiteSpace(model.AreaCode)
{
ModelState.AddModelError(nameof(model.AreaCode), "Area code is required.");
}
if (String.IsNullOrWhiteSpace(model.PhoneNumber)
{
ModelState.AddModelError(nameof(model.PhoneNumber), "Phone number is required.");
}
}
Essentially, you just first check to see if any of them have a value. Then, you individually add an error for each one that does not have a value.
That said, these broken out phone number fields are atrocious. I'm not sure where the idea came from, but it's like you just can't get people off of them now. Phone number formats vary wildly, and not every phone number actually has an "area code". It's far better to have a single "phone" field where the user can simply type their entire phone number. Then, you can use something like this port of Google's libphonenumber library to validate the number and format it into a standard form. You can even use the library to parse out the individual pieces of country code, area code, and number, if you need to store it like this. Just be prepared that the area code may not have a value and even if it does, it may not be exactly 3 digits. Same goes for number portion, as well: you can't assume it will always be 7.
Validate a phone number
var phoneUtil = PhoneNumberUtil.GetInstance();
try {
var phoneNumber = phoneUtil.Parse(model.Phone, countryISO2);
if (!phoneUtil.IsValidNumber(phoneNumber))
{
ModelState.AddModelError(nameof(model.Phone), "Invalid phone number.");
}
} catch (NumberParseException) {
ModelState.AddModelError(nameof(model.Phone), "Invalid phone number.");
}
Where countryISO2 is the two character country code: "US", "GB", etc. If you want to accept international phone numbers, you should collect the country from the user.
Format a phone number
phoneUtil.Format(phoneNumber, PhoneNumberFormat.NATIONAL);
Get component parts of a phone number
var countryCode = phoneNumber.CountryCode;
string areaCode;
string number;
var nationalSignificantNumber = phoneUtil.GetNationalSignificantNumber(phoneNumber);
var areaCodeLength = phoneUtil.GetLengthOfGeographicalAreaCode(phoneNumber);
if (areaCodeLength > 0) {
areaCode = nationalSignificantNumber.Substring(0, areaCodeLength);
number = nationalSignificantNumber.Substring(areaCodeLength);
} else {
areaCode = "";
number = nationalSignificantNumber;
}
When i use this code with dot i dont get anything...its blank but when i replace it with slash it works. Can someone tell me what is problem with this?
#{
String date = Model.Edit.BirthDate.ToString("dd'.'MM'.'yyyy.");
}
#Html.Label(date)
#{
String date = Model.Edit.BirthDate.ToString("dd'/'MM'/'yyyy.");
}
#Html.Label(date)
If i use this below i get only year because i didnt put dot at the end of year
#{
String date = Model.Edit.BirthDate.ToString("dd'/'MM'/'yyyy");
}
#Html.Label(date)
Those characters (forward slash, and dot) are not special and can just be input as you want them displayed.
For example:
DateTime.Now.ToString("dd.MM.yyyy") // 22.04.2015
DateTime.Now.ToString("dd/MM/yyyy") // 22/04/2015
In fact, I think the problem is because you are using the wrong overload for Html.Label. The parameter you are supplying is supposed to be an expression that defines which property (from Model) to use. If you want to just display a text value (and not link it to a property) then just use:
#{
String date = Model.Edit.BirthDate.ToString("dd.MM.yyyy");
}
#date
or if you want to render an html label:
<label>#(date)</label>
I am trying to setup a search in umbraco examine.I have two search fields ,material and manufacturer.when I trying to search with one material and one manufactuere it will give the correct result.but when try to search more than one material or manufacturer it doesn't give the result.here is my code
const string materialSearchFields = "material";
const string manufacturerSearchFields = "manufacturer";
if (!string.IsNullOrEmpty(Request.QueryString["material"]))
{
material = Helper.StripTags(Request.QueryString["material"]);
}
if (!string.IsNullOrEmpty(Request.QueryString["manufacturer"]))
{
manufacturer = Helper.StripTags(Request.QueryString["manufacturer"]);
}
if (!string.IsNullOrEmpty(Request.QueryString["material"]) || !string.IsNullOrEmpty(Request.QueryString["manufacturer"]))
{
var query = userFieldSearchCriteria.Field(materialSearchFields, material).And().Field(manufacturerSearchFields, manufacturer).Compile();
contentResults = contentSearcher.Search(query).ToList();
}
here my search keywors in querystring is material=iron,steel
how can we split this keyword and search done?
Thanks in advance for the help....
You are using the AND operator, in your case I think you are looking for the GROUPEDOR instead?
I was just working in an old project and grabbed this snipet from there (which I've adapted for your needs). I think it's going to help you:
public IEnumerable<DynamicNode> SearchUmbraco(string[] keywords, string currentCulture)
{
// In this case I had some diferent cultures, so this sets the BaseSearchProvider to the given culture parameter. You might not need this, use your default one.
BaseSearchProvider searcher = SetBaseSearchProvider(currentCulture);
var searchCriteria = searcher.CreateSearchCriteria(BooleanOperation.Or);
var groupedQuery = searchCriteria.GroupedOr(new[] {"manufacturer", "material"}, keywords).Compile();
var searchResults = searcher.Search(groupedQuery);
// ... return IEnumerable of dynamic nodes (in this snipet case)
}
I just split(etc) the keywords in an helper and pass them to a string array when I call this method.
Just check this infomation on the umbraco blog: http://umbraco.com/follow-us/blog-archive/2011/9/16/examining-examine.aspx
Is there a way to insert, with a DXL script, a word document as an OLE Object into any object attribute different from Object Text?
DXL function oleInsert allows to do it, but works only for attribute Object Text.
Thank you
Unfortunately there is no way I can see to do it directly but this is a good work around if your object text doesn't already have an OLE in it.
Object o = current
string filename = "PATH_TO_FILE"
oleInsert(o, filename, true)
string err = null
if (oleIsObject o){
if (oleCut o){
err = olePasteSpecial(o."OTHER_ATTRIBUTE_NAME", true)
if(!null err)
print err
} else {
print "Problem trying to cut object\n"
}
} else {
print "Does not contain an embedded object in its object text\n"
}
The true in oleInsert and olePasteSpecial are to insert the OLE as an icon. If you don't want it as an icon you can change them both to false.
Good Luck!
Just for completeness: With DOORS 9.5 the signature of oleInsert() changed:
bool oleInsert(Object o,[attrRef],string fileName,[bool insertAsIcon])
With the documentation
If the optional parameter attrRef is specified, then the OLE object is
embedded in the user-defined text attribute. If no parameter is
specified, then the OLE object is embedded in the system "Object Text"
attribute.
This makes it a bit easier.
Thanks #Twonky! That's too helpful to me.
Additionally I added a sample code from dxl reference manual.
/*
this code segment embeds an existing word document into the current formal
object
*/
string docName = "c:\\docs\\details.doc"
Object obj = current
if (oleInsert(obj, obj."my_text", docName)){
print "Successfully embedded document\n"
} else {
print "Problem trying to embed document\n"
}
I am calling a controller method using Url.action like,
location.href = '#Url.Action("Display", "Customer", new { username = "abc",name = "abcdef",country = "India",email = "abc#hmail.com",phone = "9456974545"})';
My controller method is,
public void Display(string username, string name, string country, string email, string phone)
{ }
In this method, I can get only the value of first parameter (username). Its not getting other parameter values that is passed. All other values are null.
Please suggest me, whats wrong?
By default every content (which is not IHtmlString) emitted using a # block is automatically HTML encoded by Razor.
So, #Url.Action() is also get encoded and you are getting plain text. And & is encoded as &
If you dont want to Encode then you should use #Html.Raw(#Url.Action("","")).
The answer for you question is :
location.href = '#Html.Raw(#Url.Action("Display", "Customer", new { username = "abc",name = "abcdef",country = "India",email = "abc#hmail.com",phone = "9456974545"}))';
Hope this helps
There is a problem with '&' being encoded to the '& amp;'
model binder doesnt recognise this value. You need to prevent this encoding by rendering link with Html.Raw function.
Use '#Html.Raw(Url.Action......)'