I am trying to create a snippet that creates a field and a property for that field.
I want to use pascalCase for the field and CamelCase for the property, I want the snippet to do this automatically. I can do it if I create two different literals and manually write the name for the field and the name for the property, is there a way to automatically "create" the name for the property with capital first letter with the name taken from the name of the field?
This is my current snippet code:
<CodeSnippet Format="1.0.0">
<Header>
<Title>Property etc</Title>
<Shortcut>fprop</Shortcut>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>type</ID>
<Default>int</Default>
</Literal>
<Literal>
<ID>name</ID>
<Default>propertyName</Default>
</Literal>
</Declarations>
<Code Language="csharp">
<![CDATA[private $type$ $name$;
public $type$ $name$ <<<<--- this $name$ must have its first letter capitalized in the final result
{
get
{
return this.$name$;
}
set
{
this.$name$ = value;
}
}
$end$]]>
</Code>
</Snippet>
This is the expected result:
private int propertyName;
public int PropertyName
{
get
{
return this.propertyName;
}
set
{
this.propertyName = value;
}
}
If I use a different name for the field, for example "someFieldName" the name for the property should automatically become SomeFieldName (at the time of the snippet creation of course)
I know that I can do this if I use two separate Literals, but then I have to manually write the name for the field and then write the name for the property aswell, I want to avoid writing the property name manually.
It can be done with ReSharper.
Using Template Explorer ("Extensions->ReSharper->Tools->Templates Explorer...")
create new template
private $TYPE$ $FIELD_NAME$;
public $TYPE$ $PROPERTY_NAME$
{
get
{
return this.$FIELD_NAME$;
}
set
{
this.$FIELD_NAME$ = value;
}
}
Template settings:
uncheck Reformat
Parameters settings:
PROPERTY_Name set as first element, Editable, Suggest name for a variable
TYPE set as second element, MO-2, Suggest type for a new variable
FIELD_NAME set as third element, Not Editable, Value of another variable with first character in lower case and select PROPERTY_NAME
Related
I want to use MudDatePicker element in a way where I need to be able to set a default value on load but at the same time define a onChange event for it. I am trying to do this but error says "The component parameter is used two or more times for this component". Is there a way I can do this?
<MudDatePicker #bind-Date="#DefaultValue.Value" Label="Date" DateChanged="OnDateChange"
Required="true" Class="mb-3" />
If you have a two-way binding in Blazor i.e. #bind-Date="date", you can convert it to a one-way binding with a change event which must set the value. The two-way binding is just syntax sugar and will do the same behind the scene.
<MudDatePicker Date="#_date" Label="Date" DateChanged="OnDateChange"
Required="true" Class="mb-3" />
#inject ISnackbar Snackbar
#code {
DateTime? _date = new DateTime(2021, 12, 24);
void OnDateChange(DateTime? newDate)
{
_date=newDate;
// here you can do something when the date changes.
Snackbar.Add($"Date changed to {_date}");
}
}
Here is a snippet which you can play around with: https://try.mudblazor.com/snippet/mYcPFPvLnlyEHeOF
Remove the DateChanged="OnDateChange" and change #bind-Date="DefaultValue.Value" to #bind-Date="DefaultValue". For the property DefaultValue create a getter and setter. Because you have two way binding using #bind-Date="DefaultValue", the setter part gets called every time the value is changed.
I've added some sample code below:
DateTime? _defaultValue = DateTime.Now;
private DateTime? DefaultValue
{
get => _defaultValue;
set
{
_defaultValue = value;
OnDateChange();
}
}
I am working with BIRT report, to generate it in xml formate I am writing emitter(BIRT plugin). I need an xml report which contains some repeated sections on the basis of some section in the same report. I am using subReports for that. So the report strcture is like
List--
Header--
Table---(No header and footer)
details---
Cell----
Text(Multiple text here) Some static section and dynamic data
List Details ----
Table--(No header and footer)(This table will be repeated for every record in the header part)
Details--
Cell --
Multiple Text elements ()`
List Footer---- Empty
As I am writing the emitter, I need to extract the the content of all the text elements which are in the Cell elements mainly. Now Following is the code in My emitter for sartCell method.
public void startCell(ICellContent arg0) {
System.out.println("text in Cell:: ");
System.out.println("text in Cell:: " + arg0.getInstanceID());
for(Object ie : arg0.getChildren())
{
if(ie instanceof LabelContent)
{
LabelContent lc = (LabelContent)ie;
stringBuilder.append(lc.getText());
System.out.println(lc.getText());
}
else if(ie instanceof ForeignContent)
{
ForeignContent fc = (ForeignContent)ie;
stringBuilder.append(fc.getRawValue());
System.out.println(fc.getRawValue());
}
}
}
I am able to access the Cell and all it's text content with this logic. But I want to do the same thing with all the cells of the Table in Details section of List. The problem is that Cells in the details section are giving null on ICellContent.getChildren().
And yes My startText method is not getting called at all. Following is the declaration of my emmiter,
public class XmlEmittor extends ContentEmitterAdapter {...}
Following is the rptDesign strcture,
<List>
<Header>
<Table><Detail><Cell><Text>...DynamicText....</Text>.....</Table>
</Header>
<Detail>
<Table><Detail><Cell><Text>...DynamicText....</Text>.....</Table>
</Detail>
</List>
In above structure My text element itself is feeled with XML structure I want to generate the report in. So I just want to append all the content of my xml and write it in outputstream. Please suggest, Thanks in advance
In case of Text elements,
public void startText(ITextContent text)
or
public void startData(IDataContent data) throws BirtException
will be called but in case of Dynamic Text element
public void startForeign(IForeignContent foreign) throws BirtException
will be called.
You can use the below code snippet to get the dynamic text value
#Override
public void startForeign(IForeignContent foreign) throws BirtException {
Object rawValue = foreign.getRawValue();
}
We are using the new GWT validation library in 2.5.
We are adding an aggregated list of violations to our screen. This list must display the localized field name.
#MyNotNull(foo= "Stage")
public String getStage();
Localized message needs to display
"Stage is a required field"
The message in MyValidationMessages.properties reads
{foo} is a required field
Note that annotations do not allow non-constant values to be assigned to attributes. So we have to get the locale value somehow at design time :/
This will not work
#MyNotNull(foo = injector.getLocale().errorMessage())
public String errorMessage()
How do I use localeKey to look up the locale in the locale files since the property requires a constant?
The solution is to
add something like FieldLocale.properties this is a constants lookup
Add an attribute to your annotation like localeKey
Iterate your ConstraintViolation collection
Use something like the below to get the attribute value
Look up the localized value in your FieldLocale.properties file
Copy the violation and change the message to the localized version
protected String getAttributeValue(ConstraintViolation violation, String key) {
ConstraintDescriptor descriptor = violation.getConstraintDescriptor();
if (descriptor.getAttributes().containsKey(key))
return (String) descriptor.getAttributes().get(key);
return null;
}
protected ConstraintViolation<T> copyMessage(ConstraintViolation<T> violation, String message) {
return ConstraintViolationImpl.<T> builder() //
.setConstraintDescriptor(violation.getConstraintDescriptor()) //
.setInvalidValue(violation.getInvalidValue()) //
.setLeafBean(violation.getLeafBean()) //
.setMessage(message) //
.setMessageTemplate(violation.getMessageTemplate()) //
.setPropertyPath(violation.getPropertyPath()) //
.setRootBean(violation.getRootBean()) //
.setRootBeanClass(violation.getRootBeanClass()) //
.build();
}
I am building a complex WFFM user control that extends BaseUserControl. This control has multiple fields that get prepopulated based on some business logic. One of the fields is supposed to be a drop down which shows values from a series of Sitecore items. Here is the definition of my ListField property:
private string myListField;
[VisualProperty("My List Field:", 100),
VisualCategory("Appearance"), VisualFieldType(typeof(ListField))]
public string MyListField{
get { return myListField; }
set { myListField= value; }
}
When I debug this, the content of titleFieldList is a string that contains the following XML in URL encoded format:
%3Cquery%20t%3D%22root%22%20vf%3D%22__ID%22%20tf%3D%22Value%22%3E%3Cvalue%3E%7B814FC177-2750-48D6-B7B7-4EE87012C637%7D%3C%2Fvalue%3E%3C%2Fquery%3E
which, decode, is:
<query t="root" vf="__ID" tf="Value">
<value>{814FC177-2750-48D6-B7B7-4EE87012C637}</value>
</query>
I understand the meaning of this XML. It says that all the children of the item whose ID is that Guid are supposed to be used to populate my list, using the template field "__ID" for the value and the template field "value" for the text.
Can someone help me understand what am I supposed to do to bind an asp:DropDownList to this? Is this a particular sitecore object that has been serialized and encoded?
Is there an sc:control that can handle this?
Thanks!
** EDIT **
So I tried the following piece of code
string encodedQuery = TitleFieldList;
string query = HttpUtility.UrlDecode(encodedQuery);
XDocument xmlQuery = XDocument.Parse(query);
if (xmlQuery.Element("query") != null)
{
Dictionary<string, string> nodesDictionary = new Dictionary<string, string>();
string root = xmlQuery.Element("query").Element("value").Value;
string value = xmlQuery.Element("query").Attribute("vf").Value;
string text = xmlQuery.Element("query").Attribute("tf").Value;
Item rootItem = SitecoreUtility.GetItemWithoutSecurity(new ID(root));
ChildList childList = rootItem.GetChildren();
foreach (Item child in childList)
{
string theValue = (value == "__ID") ? child.ID.ToString() : child.Fields[value].ToString();
string theText = child.Fields[text].ToString();
nodesDictionary.Add(theText, theValue);
}
titleDropDownList.DataSource = nodesDictionary;
titleDropDownList.DataTextField = "key";
titleDropDownList.DataValueField = "value";
titleDropDownList.DataBind();
}
and it works. The dropdownlist is populated with the correct data coming from the fields that were selected in the editor. I just can't believe that there is no easier way to do this. Plus how am I supposed to honor the MultipleSelectedValueField and the EmptyChoiceField if present?
Try to change the return type of your property and add attribute TypeConverter. The type specified in TypeConverter is responsible for converting raw string value to a property's return type.
ListItemCollectionConverter - is a converter provided by WFFM
[VisualProperty("My List Field:", 100)]
[VisualCategory("Appearance")]
[VisualFieldType(typeof(ListField))]
[TypeConverter(typeof(Sitecore.Form.Web.UI.Controls.ListItemCollectionConverter.ListItemCollectionConverter))]
public Sitecore.Form.Web.UI.Controls.ListItemCollection MyListField{
get { return myListField; }
set { myListField= value; }
}
We are trying to build a system in freemarker where extension files can be optionally added to replace blocks of the standard template.
We have gotten to this point
<#attempt>
<#include "extension.ftl">
<#recover>
Standard output
</#attempt>
So - if the extension.ftl file exists it will be used otherwise the part inside of the recover block is output.
The problem with this is that freemarker always logs the error that caused the recover block to trigger.
So we need one of two things:
Don't call the include if the file doesn't exist - thus the need to check for file existence.
-OR-
A way to prevent the logging of the error inside the recover block without changing the logging to prevent ALL freemarker errors from showing up.
easier solution would be:
<#attempt>
<#import xyz.ftl>
your_code_here
<#recover>
</#attempt>
We've written a custom macro which solves this for us. In early testing, it works well. To include it, add something like this (where mm is a Spring ModelMap):
mm.addAttribute(IncludeIfExistsMacro.MACRO_NAME, new IncludeIfExistsMacro());
import java.io.IOException;
import java.util.Map;
import org.apache.commons.io.FilenameUtils;
import freemarker.cache.TemplateCache;
import freemarker.cache.TemplateLoader;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
/**
* This macro optionally includes the template given by path. If the template isn't found, it doesn't
* throw an exception; instead it renders the nested content (if any).
*
* For example:
* <#include_if_exists path="module/${behavior}.ftl">
* <#include "default.ftl">
* </#include_if_exists>
*
* #param path the path of the template to be included if it exists
* #param nested (optional) body could be include directive or any other block of code
*/
public class IncludeIfExistsMacro implements TemplateDirectiveModel {
private static final String PATH_PARAM = "path";
public static final String MACRO_NAME = "include_if_exists";
#Override
public void execute(Environment environment, Map map, TemplateModel[] templateModel,
TemplateDirectiveBody directiveBody) throws TemplateException, IOException {
if (! map.containsKey(PATH_PARAM)) {
throw new RuntimeException("missing required parameter '" + PATH_PARAM + "' for macro " + MACRO_NAME);
}
// get the current template's parent directory to use when searching for relative paths
final String currentTemplateName = environment.getTemplate().getName();
final String currentTemplateDir = FilenameUtils.getPath(currentTemplateName);
// look up the path relative to the current working directory (this also works for absolute paths)
final String path = map.get(PATH_PARAM).toString();
final String fullTemplatePath = TemplateCache.getFullTemplatePath(environment, currentTemplateDir, path);
TemplateLoader templateLoader = environment.getConfiguration().getTemplateLoader();
if (templateLoader.findTemplateSource(fullTemplatePath) != null) {
// include the template for the path, if it's found
environment.include(environment.getTemplateForInclusion(fullTemplatePath, null, true));
} else {
// otherwise render the nested content, if there is any
if (directiveBody != null) {
directiveBody.render(environment.getOut());
}
}
}
}
I had this exact need as well but I didn't want to use FreeMarker's ObjectConstructor (it felt too much like a scriptlet for my taste).
I wrote a custom FileTemplateLoader:
public class CustomFileTemplateLoader
extends FileTemplateLoader {
private static final String STUB_FTL = "/tools/empty.ftl";
public CustomFileTemplateLoader(File baseDir) throws IOException {
super(baseDir);
}
#Override
public Object findTemplateSource(String name) throws IOException {
Object result = null;
if (name.startsWith("optional:")) {
result = super.findTemplateSource(name.replace("optional:", ""));
if (result == null) {
result = super.findTemplateSource(STUB_FTL);
}
}
if (result == null) {
result = super.findTemplateSource(name);
}
return result;
}
}
And my corresponding FreeMarker macro:
<#macro optional_include name>
<#include "/optional:" + name>
</#macro>
An empty FTL file was required (/tools/empty.ftl) which just contains a comment explaining its existence.
The result is that an "optional" include will just include this empty FTL if the requested FTL cannot be found.
You can use also use Java method to check file exist or not.
Java Method-
public static boolean checkFileExistance(String filePath){
File tmpDir = new File(filePath);
boolean exists = tmpDir.exists();
return exists;
}
Freemarker Code-
<#assign fileExists = (Static["ClassName"].checkFileExistance("Filename"))?c/>
<#if fileExists = "true">
<#include "/home/demo.ftl"/>
<#else>
<#include "/home/index.ftl">
</#if>
Try this to get the base path:
<#assign objectConstructor = "freemarker.template.utility.ObjectConstructor"?new()>
<#assign file = objectConstructor("java.io.File","")>
<#assign path = file.getAbsolutePath()>
<script type="text/javascript">
alert("${path?string}");
</script>
Then this to walk the directory structure:
<#assign objectConstructor = "freemarker.template.utility.ObjectConstructor"?new()>
<#assign file = objectConstructor("java.io.File","target/test.ftl")>
<#assign exist = file.exists()>
<script type="text/javascript">
alert("${exist?string}");
</script>