In our application, we have a collection of data items, each with a DisplayedName property. This property should be localized, i.e. it should be displayed in the language selected by the user. Therefore, another property, DisplayedNameResourceKey, specifies which resource should be returned by the DisplayedName property.
In simplified code this means something like this:
public string DisplayedName
{
get
{
return MyResources.ResourceManager.GetObject(this.DisplayedNameResourceKey);
}
}
public string DisplayedNameResourceKey
{
get;
set;
}
Now, the problem is: The user should be able to edit these items including the DisplayedName, or more precisely the DisplayedNameResourceKey. And not only this, but the user should also be able to somehow define new resources which he can then reference. That is, he can either choose from a predefined set of resources (some commonly used names), or define a custom resource which then needs to be localized by the user as well.
However, the user cannot add custom resources to MyResources at runtime and without compiling. Therefore, another approach is needed. It does not have to be an extremely user-friendly way (e.g. UI is not required) because this will typically be done by our service engineers.
I was thinking about using a txt or csv file containing pairs of resource keys and the corresponding translations. A separate file would exist for every language at a predefined location. But I am not really satisfied with that idea because it involves a lot of work to resolve the resources.
Does anyone know a good approach for such a situation?
You could consider putting the resources in a database. In this way, you keep it fairly dynamic and fast.
E.g. a table with 3 columns: resource key, language, message. You should probably create a composite index on the resource key and language columns for fast lookup.
Related
I should model a system that clients can apply some configuration on separated entities.
Let me explain with an example:
We have users that have a config tab in their dashboards.
We have a feature to send notifications on their browsers and we have a feature which we can send an email to them.
We also have a feature as a pop-up.
The user should be able to modify our default notification message, modify our default email template, modify our default text on email or elements.
For the pop-up, The user should be able to modify the width and height of the pop-up, change the default texts, modify background color, change the button location on the pop-up.
And when I want to send an email to the user I should apply these settings on the template then send the email. Also when the front-end wants to show those pop-ups, wants to get these configs from my API and apply them.
These settings will be more and more in the future. So I can not specify a settings table with some fields. I think it is not a good idea.
What can I do? How to design and model this scenario? What are the best practices?
Can I use a NoSQL like MongoDB instead of a relational database?
Thanks a lot.
PS:
I am using Django to develop this system.
I have built similar sub-systems before, by hand.
I don't know much about Django, but do some research to see if it has any "out of the box" or community developed / open source add-ons that do what you want.
If you have to do it yourself...
A key-value pair is not going to be enough, but it's close. You only need a simple data structure:
ID (how your code recognizes this property), e.g. UserPopupBackgroundColor.
Property name (what the user see's / how they recognize this property in the UI), e.g. "Popup Background Color".
Optional - Data type. This is essential if you want to do any sensible input validation. E.g. pop up height should probably expect an integer, and have a sensible min/max value on it, where as an email address is totally different.
Optional, some kind of flag to identify valid properties.
That last flag is bit of an edge case, but it's useful if you use the subsystem to hold more properties than you want users to have access to. E.g. imagine you want to get a list of all properties and display the list to the user - are there any 'special' ones you need to filter out that they should not see?
You then need somewhere to put the values, and link them to the user:
Row ID / GUID. You can use a unique constraint across the User and PropertyID if you wanted to instead, but personally I find a unique row ID is a reliable and flexible approach for most scenarios.
UserID.
PropertyID - refers to ID mentioned above.
PropertyValue
Depending on how serious you need to get, you can dump all the values into the one PropertyValue column (assuming you're persisting this in a database) - which means that column needs to be a string, or, you can add a column per data type.
If you want to add a column per data type, don't kill yourself. The most I have ever done is:
PropertyValue_text (text/varchar)
PropertyValue_int (or double)
PropertyValue_DateTime (date/time - surprise!!)
So when I say 'column per data type' I mean per data type your stack needs/wants to handle - not the 'optional' data types you define in the logic - since that data type is partially just about input validation.
Obviously if you use different logical data types, you can map those to data type columns in the database. The reasons for doing this (using the different data types in the database are:
To reduce the amount of casting you need to do (code to database, and vis-a-versa).
To leverage database level query features, which can be useful. E.g. find emails values and verify them; find expired date values; etc.
It takes a bit of work to build all this, but it's powerful once you get set-up because you can add any number of properties. If you are using the 'full' solution with explicit data types then adding new logical data types isn't too painful if you already have a few set-up.
Before you design and build this, think about future reuse, and anyway you can package it up for later - or community use. Remember it impact all layers (UI, logic and data).
Final tip - when coming up with the property ID's (that the code uses) make them human readable, and use some sort of naming convention so that adding new ones later is easy and follows a predictable path.
Update - Defining Property and PropertyValue in database tables is an obvious way to go. Depending on the situation you can also define Property in code - especially if you don't add new ones or change existing ones very frequently. Another bonus is that if you're in an MVP situation you can use the code effectively as a stub, and build out the database/persistence part for that later.
I have started to model some city-transport data (bus lines and bus stops) for a community project. The data arrived to me as JSON files, and I'd like to create some classes from it, considering the already available data at first.
There is a BusLine object, whose JSONs don't contain information about which BusStop are related to it.
And there is a large collection of BusStop, of which one property is BusLines, a collection of (references to) bus lines which pass about that stop.
So far I have modelled this (C# style, but intended just for visualization at first):
public class BusLine
{
public String code;
public String name;
public List<DirectPosition> route;
}
public class BusStop
{
public String code;
public DirectPosition location;
public List<BusLine> busLines;
}
My doubt, from now, is this: most probably, I'll want to know the BusStops associated with a given BusLine. I imagine some possible ways of doing it, but am not sure at all how this rather trivial situation should be addressed. My naive thoughts:
Create a getStops() method that would look somewhere to check which stops existed along that route, and create such list on-the-fly;
Create an explicit List<BusStop> stops property in BusLine class (that sounds very wrong);
Eliminate containment altogether and create a third, "Relation" kind of class that would manage (somehow) the relations between those classes. That would mean the knowledge about those relations, extracted from the JSON files, wouldn't be stored "inside" the entities, but somewhere else.
I am pretty sure this is a common pattern (I'd bet there's at least one design pattern for that), but my current level of knowledge gives me no clue...
Thanks for any help!
I'm trying to write a common test module for a localized application.
The first issue I'm having is the fact that MenuItems do not support controlname attributes. Currently my menu items are located via text or accessiblename attribute. Is there a way to support controlname attribute?
I've tried to make text and accessiblename attribute point to a variable and then bind the variable to some external dictionary. As I understand the external data sources are treated as rows which contain various data items for a single variable. I don't see a way to use external data sources that treat first column as variable name and second column as variable value. Is there a way to achieve such functionality?
I've thought about a way to extend RanorexXPath to accept functions. Then I could write something like ...menuitem[text=localizationService.Translate("#ADMINISTRATION") and have Ranorex find the menu item based on the result of localizationService.Translate function. Is there a way to do this?
Finally I've somewhat managed to get the result I need by using global variables and module variables. What I did was create a module that uses localizationService to fill module variables with correct data. Next I bind the module variables to global parameters and use the data in subsequent test. This is quite error prone and difficult to implement for large number of variables. Is there a way to access and set global variables directly from code (without the need to use binding)?
If any of the 4. points is possible please let me know.
The recomendation from Ranorex support team:
In general only the whole menu is a control in WinForms. The elements within that control (MenuItems) can only be recognized via MSAA.
The problem is that the "Name" attribute of the MenuItems is not accessible.
As workaround I would suggest to use the attribute "AccessibleDescription" in your application in order to automate the menu. This attribute can also be used for language independent names.
In automation of a WPF application (using UI Automation; VSTS 2010), we were adding all the Automation IDs in a Resource File manually and then access it one by one. Considering the application can expand any time, manually adding these IDs can become tedious.
So, is there any tool available which can create this for us? i.e. Get all the ids in a hierarchical format and store it in a file (xml or csv), and then we could parse it whenever required.
I was hoping for a tool like UISpy, which not only can spy all the elements but also export the same.
Do such tools exist? Or is there any alternate approach?
Any valuable feedback is highly appreciated.
Thanks!
I do like this:
public static class AutomationIds
{
public static readonly string MyDataGridId= Create();
private static string Create([CallerMemberName] string name = null)
{
return name;
}
}
<DataGrid AutomationProperties.AutomationId="{x:Static local:AutomationIds.MyDataGridId}"
... />
Then in tests
var dataGrid = window.Get<ListView>(AutomationIds.MyDataGridId);
Assign the automation IDs directly in XAML, then parse XAML files since they are XML after all...
Let's see...
First, I think that your data is not hierarchical - just because a control can be dynamically assigned to be a child of another.
If we change the problem to a subset: "how can we get a hierarchical view of the controls at a time t?" then we can answer this with MS UIA, and say, using a simple RawViewWalker (just a simple breadth-first search on the walker, starting from your main window will do - of course while the application is running so that UIA can reach and query it).
But this subset will not satisfy your initial question, because you'll probably see a portion of your whole ui collection (since some will be hidden / not activated yet at time t).
So it becomes very hard to use a UIA based tool (such as uispy) because then you'll have to set the application view to different states to reach all the controls in your application at different times t1, t2...
I would suggest parsing all your xmls at the same time and build a complete tree of the application's "static" control map, which I believe would be closest to what you're asking for.
Given that this is an old question, I doubt it matters anymore, but just wanted to make the distinctions here.
This is something I have been struggling about for some time now. The thing is: I have many (20 or so) static arrays of values. I say static because that is how I'm actually storing them, as static arrays inside some domains. For example, if I have a list of known websites, I do:
class Website {
...
static websites = ["web1", "web2" ...]
}
But I do this just while developing, because I can easily change the arrays if needed, but what I'm going to do when the application is ready for deployment? In my project it is very probable that, at some point, these arrays of values change. I've been researching on that matter, one can store application properties inside an external .properties file, but it will be impossible to store an array, even futile, because if some array gets an additional value, the application can't recognize it until the name of the new property is added where needed.
Another approach is to store this information in the database, but for some reason it seems like a waste to add 20 or more tables that will have just two rows, an id and a name.
And the last option, as far as I know, would be an XML, but I'm not very experienced with those. It seems groovy has a way of creating and reading XML files relatively easy, but I don't know how difficult would be to modify an XML whose layout is predefined in the application.
Needless to say that storing them in the config.groovy is not an option since any change will require to recompile.
I haven't come across some "standard" (maybe a best practice?) way of dealing with these.
So the questions is: Where to store these arrays?
Use Enum for a fixed set of attributes. Do this, if you rely at some places in your code on some concrete values.
If you do not rely on the attributes within your code (which you obviously don't), use a String-type. In this case, if you need to provide a select box, just do a distinct-query on this property in your database.
Default: Use a domain class per dynamic set of attributes. Another table is OK.
For something as simple as arrays you should use groovy own type of property files. They allow you too define properties as proper groovy variables (not just strings) and obviously loading them would be done dinamically in a simple way by using ConfigSlurper. For an example on how to use this kind of file you can have a look at the following ConfigSlurper:
For defining properties:
my.property.array=[1,2,3,4]
For loading property files:
def config = new ConfigSlurper().parse(new File('myconfig.groovy').toURL())
assert [1,2,3,4] == config.my.property.array
Tip: When you want to access the property files you want to do it in a way that can work for any environment. To make paths environment-independent use the following path as the root path:
import org.codehaus.groovy.grails.commons.ApplicationHolder
def ctx = ApplicationHolder.application.mainContext.servletContext
def rootPath = ctx.contextPath