I am new with MDS, and I have a question about one to many relation mapping in MDS
I have a product, contains descriptions in multiple languages. I have created two entities with derived hierarchy structure: product (P_ID, P_name)and Addtional description(P_ID, P_Name_in_German, P_name_in_English).
Additonal description is a drop down from product table from MDS UI, but I only want to populate info that releated with its same P_ID. How can I achieve that? Can I use business rules here and how it should look like?
(2012 Master data service' web interface)
I have also faced a similar problem. I have decided to add multiple fields for languages and apply business rules for them. Let's see how it would work for your entity:
Product entity
{
Code
Name
Name_in_English (text)
Name_in_German (text)
Default_language (domain based, points to Languages entity)
}
Languages entity
{
Code
Name
}
Add values to the Languages entity:
Code = "EN", Mane = "EN"
Code = "DE", name = "DE"
Now we need to add the following business rules to the Product entity:
BR1:
{
IF Condition - Equals: Default_language equals "EN"
THEN Action - Change value: Name = Name_in_English
}
BR2:
{
IF Condition - Equals: Default_language equals "DE"
THEN Action - Change value: Name = Name_in_German
}
After that You will see the product names in your product entity only in proper language which is chosen by drop-down field Default_language.
The second option:
If You want user to see only the Name field and don't want him to see additional fields,
You can hide those fields (Name_in_English and Name_in_German) by setting their width to zero.
Moreover, You can use attribute groups to separate two modes of view:
first mode (for the regular user) - You see only Code and Name
second mode (for the administrator) - You see fields: Name_in_English, Name_in_German, Default_language.
For it to work You need to create two attribute groups:
1) attribute group "EN" (add attributes Name and Code to the group)
2) attribute group "DE" (add attributes Name_in_English, Name_in_German, Default_language to the group)
Hope something of that is helpful!
You're missing something. You said you have a derived hierarchy structure but you don't show a domain based attribute on the Additional description entity with a pointer back to the Product entity. Perhaps you were thinking that the P_ID for Additional Description is the pointer back but it isn't (based on your explanation). It is the entity Code identifier for the Additional Description entity and not the key you need that points back to Product. Perhaps you meant One to One. One to Many implies you have a separate Parent_P_ID back to the Product entity.
Add the Domain Based Parent_P_ID attribute to the Additional Description entity and then reconstruct your derived hierarchy structure. This may not be that helpful because I think you have left something out of the explanation of what you are trying to do.
Hi Cocunuts,
We can not assign derived hierarchy to entities in MDS 2012,but we can achieve this in MDS 2016 , Your Domain based attribute(Drop down) cannot be further filtered in MDS 2012.
Related
I need to train watson assistant on the following utterance, what is the order status of Bob/Jane or some name.
I tried with #sys-person but it does not recognize all names.
I defined an intent like this
what is order status of #name
and created entity #name as \b[A-Za-z0-9]\b
This is a good use for contextual entities. You can read up on those here:
Contextual Entities with IBM Watson Assistant
All about entities: Contextual entities with Watson Assistanthttps://medium.com/ibm-watson/all-about-entities-contextual-entities-with-watson-assistant-part-2-7697d2b73db0)
The idea is that you don't need your bot to know all possible names in advance, but instead it can recognize a name based on the context within an intent.
To set this up, you'd go to your order status intent and add some training examples such as:
what is the order status of Name
what is the order status of Another Name
what is the order status of Yet Another Name
(These examples can have any kind of name, whether fake or real.)
And then you'll annotate each of those to associate the name with the #name entity, by double-clicking on the name portion of the training examples (i.e. Name, Another Name, Yet Another Name) to bring up the entity selection UI and specifying your #name entity.
After Watson finishes training, you can test it in the "Try it out" window. Enter something like "what is the order status of Charles Flint" or "what is the order status of Thomas Watson" and you should see your #name entity matched. From there, you can access the name specified by the user with #name.value.
Hi JohnDon't wish to dismiss your entity pattern, however from experience I have seen its almost impossible to determine a complete list of people names. I use both #sys-person and my own #names entity which contains over 6,000 common names, and we are still adding missing values to the list. We also have a #bad_names list which contains names that match common words like; summer, cherry, star, cj, etc. By using both your intent or #sys-person or #names, etc in your condition you have a good chance to catch a high percent of the users messages.
I have a question about how to access fields from pre-existing pages and display them in a different page.
For example I have a document type called: "People" and I create a page for several people so that the structure of my content section looks like this:
Home
page1
page2
page3
People
person1
person2
person3
The document type "People" uses contains the fields:
Name, Age, Job, Description all as textboxes.
What would you suggest is the best way of accessing the values in these fields for each page so that you loop through each person under the parent "People" and display their name/age/desc?
Using:
#{
var selection = Umbraco.TypedContent(1108).Children()
.Where(x => x.IsVisible());
}
#foreach(var item in selection){
}
I can only access the metadata for each page such as #item.Id but I cant work out how to access the fields so say #item.Name returns the persons name.
Any help will be really appreciated! Cheers.
What you get from the query above is instances of your content as IPublishedContent. This is a pretty generic interface for any type of published content, so you will not be able to directly access the specific custom properties you have defined on your document types, as normal C# properties on this object.
However - if you have ModelsBuilder enabled in your site, you should be able to do the following and get the children returned as mapped POCO classes:
var selection = Umbraco.TypedContent(1108).Children<Person>()
(or <People> .. depending on what the actual document type alias of the child items is called)
If you are not using ModelsBuilder, you would have the option of just doing this inside your foreach loop to get the values of your properties instead:
var age = item.GetPropertyValue<string>("age");
Bonus note: please rename your Name property to something else (fullname or something like that). Using Name will clash with the built-in property used for the node name :)
I have a MySQL database (that is later imported into Doctrine) set up that links 3 different tables by way of foreign keys. The relationship is as follows: Many As go to one B, and many Bs go to one C. For the web page that I am trying to create, I need some of the related B's information on a page about A, while being categorized by C.
Think of it like this: A is "dog_food", B is "company", and C is "company_category". That is, on a page displaying different kinds of dog food, I need to display information about the manufacturing company; I only display those dog foods based on how the user specifies what kind of company they want to buy from.
Pulling information dynamically from A is trivial, since the repository is pulled and the rows exist as entities. Say, {{ dog_food.price }} would call (if specified in a for loop, this is Twig code) a single instance's price.
I have read about the #OneToOne, #OneToMany, etc. annotations, but have not been able to find a way to easily utilize their effects inside of a Twig template. The aggregate entities and repositories for all 3 tables exist as variables in the Controller. It should be mentioned that, continuing with this example, that there is a single companyID field in table B corresponding to multiple dog foods, and a single categoryID associated with multiple companies.
What happens if I want to list the company name above the price? How do I access that information in Doctrine, and furthermore, in Twig?
I will translate what you've said above into code that I would effectively write if I was you:
So, I assume that, along with the mapping you defined , your company category entity is called 'Company_category', your dog food entity is called 'Dog_food'.
I would pass the id of the company_category to an action in my controller,
then, I would retrieve all the companies that belong to that company_category, something like this:
public function xyzAction($id){
$companies=$this->getDoctrine()->getRepository('XYZYourBundle:Company')
->findBy(array('company_category'=>$id));
//Hold on I will just complete it
}
Then I would retrieve all the dog foods objects from my DB, that the company's exist in $companies, the result returned in the first line of code,
to do this, I would first:
1-Define my own criteria:
this would help you define a complex , powerful conditions and it's easy to use.
2-Use my criteria to filter the result of the repository, this would be useful
So let's update our action:
public function xyzAction($id){
$companies=$this->getDoctrine()->getRepository('XYZYourBundle:Company')->findBy(array('company_category'=>$id));
$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria->where($criteria->expr()->in('company',$companies));
$dogfoods=$this->getDoctrine()->getRepository('XYZYourBundle:Dog_food')->matching($criteria)
//Hold on I will just complete it
}
and finally render our dogfood objects to a twig template:
public function xyzAction($id){
$companies=$this->getDoctrine()->getRepository('XYZYourBundle:Company')->findBy(array('company_category'=>$id));
$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria->where($criteria->expr()->in('company',$companies));
$dogfoods=$this->getDoctrine()->getRepository('XYZYourBundle:Dog_food')->matching($criteria)
return $this->render('XYZYourBundle:test.html.twig', array(
'dogfoods'=>$dogfoods));
}
Now, let's place ouselves in a twig template, we're gonna iterate through our $dogfoods objects and we will display some information, assuming you defined the needed getters and setters;
{% for dogfood in dogfoods %}
{{dogfood.price}}
{{dogfood.company}}
{% endfor %}
Edit :
you can get the company's name by either:
-implement a tostring method that returns the company's name and in twig use
{{dogfood.company}}
or
-in twig, use
{{dogfood.company.name}}
Hope this helps you, if something doesn't work just tell me.
I am attempting to access values in the Categories and Keywords information for a Tridion Publication via a Razor TBB in Tridion 2011. The Razor documentation lists the following example code:
<ul>
#foreach (var keyword in Publication.MetaData.SomeKeywordFields) {
<li>#keyword.Title (#keyword.Id)</li>
}
</ul>
I have a Keyword inside of a Category though... in fact, that's the only way I am myself aware that you can even have a Keyword in Tridion, but correct me if I am wrong. Extrapolating from the example's syntax, I tried the following where "myCategory" is a Category in the publication, and "myKeyword" is a Keyword inside of the myCategory Category:
#foreach (var keyword in Publication.MetaData.myCategory) {
if(#keyword.Title == "myKeyword") {
#keyword.Title
}
When I run this template, I get an error stating that DynamicItemsFields: Key 'testcategory' Not Found In ItemFields (Object reference not set to an instance of an object)
Can anyone help with identifying if it is even possible to do what I am attempting here (as it seems like it is based on the documentation but still not sure) and if so, provide an example of the correct syntax?
You're almost there with your code except that you're using the actual CategoryName. As Puf commented, you have to use the "fieldname" of you Publication Metadata not the actual CategoryName. You should just change the "myCategory" to the actual fieldname
#foreach (var keyword in Publication.MetaData.*<<FIELDNAME>>*) {
if(#keyword.Title == "myKeyword") {
#keyword.Title
}
}
[FIELDNAME] --> is the XMLName of publication metadata schema.
Keywords are indeed always within a Category or another Keyword. But they are used within items like Components and (as in the example) metadata on Publications, Folders, etc.
The example from the documentation is outputting each value of a multi-valued metadata Keyword field on the Publication (i.e. "Allow Multiple Values", "Values selected from a list" and "Category" all checked in the Metadata Schema).
If you are trying to do something similar, you can indeed modify the name of the field and it will work. From your question, however, it seems like you are trying to loop over all Keywords within a certain Category - which requires a different approach.
For that, you would need the equivalent of a GetList call within your TBB. I'm not familiar enough with the Razor mediator to provide sample code for that, sorry.
Thanks to Ram G in chat:
The Publication itself, typically your 010, 020... 050 etc. levels, can have a metadata schema attached to them as well. The XMLName of the field being targeted by the Razor logic block above is actually the field name of this metadata schema item, not the name of the Category itself. In the metadata schema for the publication, if you select the Design tab, Make your XML field for the item a "Text" type, select "Options will be selected from a list", by default, another Checkbox will appear called "Category" which, if checked, automatically pulls in the full list of Category items present in that publication. So, when that Field is targeted by the Razor logic now, it is in multiple steps targeting the Category value as well.
Thanks again Ram G
I am currently evaluating SQLAlchemy for a project. Here is my schema:
a LANGUAGE table, with a row for each language supported
a TRANSLATION table with (ID, LANGUAGE_ID, STR)
various tables will, instead of storing text, store TRANSLATION_IDs, for example, BOOK(ID, TITLE_TRANSLATION_ID, ABSTRACT_TRANSLATION_ID)
Now, assuming each request has the current language ID available (for example, through a thread variable...), I would need SQLAlchemy to automatically join the TRANSLATION table, and thus have text fields in the current language. Something like:
class Book(Base):
id = Column(Integer, primary_key=True)
title = TranslatableText()
abstract = TranslatableText()
When retrieving, the ORM would automatically join to the TRANSLATION table with the current language ID, and my_book.title would give me the title in the current language.
I also need this to work across relations: if a class contains foreign keys to other classes that also contain translatable text fields, I would ideally like those to be retrieved too.
Lastly, I would also need to be able to get to the TRANSLATION_ID for each field, for example through my_book.title_translation_id.
I am not expecting a complete solution, but I'd like to know if something like this is feasible, and where to start.
You have to use the concept of http://docs.sqlalchemy.org/en/latest/orm/extensions/declarative.html#mixin-and-custom-base-classes
Create one top level class and write some funciton like read, write and create. Always call that function to create or read data from the database.
If you dont want to implement the mixin classes then also you can use event http://docs.sqlalchemy.org/en/latest/orm/events.html#sqlalchemy.orm.events.MapperEvents.translate_row