Umbraco multilanguage with URL change - c#

I am working with Umbraco v7.x. I have few static pages and they need to be added in two languages(en/da).
I know there are two ways to translate
1- Copy folder and assign different culture and hostname and add fields data according to language.
2 - Use dictionary items.
But my problem is customer wants to have custom fields on all pages so he can change static page data without having the need to ask developer. So if I use first method to change language that would also change URL which is not required for this solution.
Second I use dictionary than how can customer can change field data because he had to go to dictionary items and make any change there. This is not a problem but text needs to be formatted and this is not possible if I use dictionary items.
Any work around to this problem.
Thanks

I recommend using Vorto if you want a 1:1 translated site (meaning each piece of content has a translation for each language. Use dictionary items for text that was hard-coded into your template but Vorto will wrap your property editors so that you can edit each language in the same node. You can then use HasVortoValue() and GetVortoValue() instead of HasValue() and GetPropertyValue() methods that come with Umbraco. This will return the correct value based on the culture of the request. You will also need to configure Umbraco to load the multilingual content by setting a host name and associate that with a culture. You do that by selecting "Culture and Hostnames" in the contextual menu for the home node and and click "Add Domain" (you will need to have first added the language in the Settings section):
Alternatively, if you want to use a subfolder for each language instead of a differeent domain (e.g. sitename.com/english instead of english.sitename.com) you can create a custom Content Finder. I have written a couple blog posts on how to do that here and here.

Related

Read/Write SharePoint User Field [Word 2010 VSTO]

I've been experimenting with reading SharePoint 2013 Site Column metadata from within a Word 2010 Application-level C# VSTO.
For testing I've set-up Site Columns for every type that SharePoint uses, then created a Document Content Type that ties to them all -- thus all these columns are embedded into the Word document (looks to be stored within customXml within the document file).
By reading from the _Document.ContentTypeProperties property within the VSTO's code, I can access most types, but I'm having difficulty accessing a 'Person or Group' Site Column's data -- I'm getting COM Exceptions attempting to read or write to an item's .Value property.
By looking at the XSD schema in customXml, I can see a single-value User column is made up of three values: DisplayName (type string), AccountType (type string) and AccountId (type UserId) -- however I don't see a way to read/write from/to this within the VSTO? Multi-value User columns appear to be completely different, and are made up of two string values: an ID (appears to be the SharePoint user's ID) and a string-based ID (or at least that's what I think the i:0#.w|domain\userid is, anyway).
Word itself can edit both single- and multi-valued User column data via the Document Panel, but only if Word is currently connected to SharePoint -- otherwise the functionality is disabled. I'd assume the same would be true for the VSTO, if I could access the values at all...
My two questions are:
Is there a way to read/write single- and multi-value User fields from within VSTO code (even if it's not via the _Document.ContentTypeProperties property)?
Is there a way to do Q1 when if not connected to SharePoint (if, say, the values are known to the code)?
(I've been somewhat overly verbose in case my workings so far are useful to someone else even if I get no answers; there doesn't seem to be a great amount of information about this anywhere)
With some provisos, I believe you can do read/update these fields using VSTO - although I haven't actually created a working example using VSTO, the same objects as I'd use in Word VBA are available - the code snippets below are VBA.
The person/group values that are displayed in the DIP are stored in a Custom XML Part, even when the SharePoint server is unavailable. So the problem is not modifying the values - it's a CRUD operation, in essence - but knowing what values you can use, particularly in the multi-valued case. If you know how to construct valid values (let's say you have an independent list of email addresses) then you can make the modifications locally. Personally, I don't know how I would construct a valid value for the multi-valued case so I'd basically have to contact the server.
So assuming you have the data you need to update locally...
When SharePoint serves a Word Document, it inserts/updates several Custom XML Parts. One contains a set of schemas (as you have discovered). Another contains the data. All you really need to do is access the correct Custom XML Part, find the XML Element corresponding to your SharePoint user/group column, then it's a CRUD operation on the subElements of that Element.
You can find the correct Custom XML Part using the appropriate namespace name, e.g.
Const metaPropDataUri as String = _
"http://schemas.microsoft.com/office/2006/metadata/properties"
Dim theDoc as Word.Document
Dim cxp as Office.CustomXMLPart
Dim cxps as Office.CustomXMLParts
Set theDoc = ActiveDocument
Set cxps = theDoc.CustomXMLParts.SelectByNamespace(metaPropDataUri)
If there is more than one part associate with that Namespace, I don't know for sure how to choose the correct one. AFAIK Word/Sharepoint only ever creates one, and experiments suggest that if there is another one, SharePoint works with the first one. So I use
Set cxp = cxps(1)
At this point you need to know the XML Element name of the person/group column. It may be the same as the external name (the one you can see in the SharePoint list), but if for example someone called the Sharepoint column "person group", the Element name will be "person_x0020_group". If the name isn't going to vary, you can get it from the schema XML as a one-off task. Or it may be easy to generate the correct element name from any given SharePoint name. Otherwise, you can get it dynamically from the Schema XML, which you can get (as a string) using
theDoc.ContentTypeProperties.SchemaXML
What you need to do then is find the element with attribute ma:displayName="the external name" and get the value of the name attribute. I would imagine that's quite straightforward using c#, a suitable XML object, and a bit of XPath, say
//xsd:element[#ma:displayName='person group'][1]/#name
which should return 'person_x0020_group'
You can then get the Element node for your data, e.g. something along the lines of
Dim cxn As Office.CustomXMLNode
Set cxn = cxp.SelectSingleNode("//*[name()='person_x0020_group'][1]")
Or you may find it's preferable to get the namespace Uri of the Elements in this Custom XML Part and use that to help you locate the correct node. The name is a long hex string assigned by SharePoint. You can get it from the Schema XML using, e.g.
//xsd:schema[1]/#targetNamespace
Once you have your node, you would use the known structures (i.e. the ones you have found in the Schemas) to get/modify/create child nodes as required.
of course you can. You should use the SharePoint Client-side Object model (CSOM) to manipulate SharePoint data from a location away from the server. The only thing you will need is the URL of your SharePoint site.
You can then connect through CSOM like this:
ClientContext context = new ClientContext("SITEURL");
Site site = context.Site;
Web web = context.Web;
context.Load(site);
context.Load(web);
context.ExecuteQuery();
See here an example to set a single user field:
First get the ID of the user through ensuring the username
u = context.Web.EnsureUser(UserOrGroupName);
context.Load(u);
context.ExecuteQuery();
To set the value, you can use this string format:
userid;#userloginname;#
To set the field use this:
item[myusercolumn] = "userid;#userloginname;#";
item.Update();
context.ExecuteQuery();
To set a multi user field, you can use the same code, just use ;# to concat the different usernames, such as:
item[myusercolumn] = "userid1;#userloginname1;#userid2;#userloginname2;#userid3;#userloginname3;#";
item.Update();
context.ExecuteQuery();
Hope this helps

Grouping identical labels and changing text all together - c# / Javascript

I have a asp.net C# MVC Razor view that allows the user to change units for input fields from metric to imperial. There are about a dozen labels that all need to be changed at the same time to the same text, no exceptions ("mm" => "inch" and visa verse).
Since the dot net framework requires each element to have unique ID fields I'm trying to find another way to group them all together and change them on the client side.
It seems silly to give each one a unique ID and call each one individually in a if/then statement to switch measurement systems when they are identical. There has to be a better way.
I attempted to use #ViewBag but I found that javascript can only read the value and can't change it on the client side.
#Html.Label("display_units", "mm", new { id = "lbl_units" })
Thanks for your help and suggestions.
Give your labels a common css class like "display-units". Then from Javascript code, you can use jQuery to find all labels of that class and change the text:
$(".display-units").text('mm');
KnockoutJS was written to solve this kind of problem, ie, binding your viewmodel to your view.

HTML tags in database bad practice or good practice?

Sometimes I need to format specific data or part of it that comes from the database .
For example :
If i have a desc (stored in DB) like this :
HTML 4 has been tweaked, stretched and augmented beyond its initial scope to bring high levels of interactivity and multimedia to Web sites. Plugins like Flash, Silverlight and Java have added media integration to the Web, but not without some cost.
and i wanna to format the last line , change the font and color for example .
What 's the best practice to do this ?
embedding HTML tags in my database ??Is this safe and the best practice or there 's some way to separate the structure layer from the presentation layer from the behavior layer ?
If you plan to manipulate or search upon the stored data then do not store HTML markup in your database. Imagine that at some point you're asked to change the fonts from Tahoma to Georgia, change <b> tags to <strong> or allow the users to search on the HTML column; and searches for strong end up returning irrelevant information because strong is also a frequently used HTML tag.
Storing HTML markup in your database is also a bad idea if you do not check what is being stored. A malicious script tag such as <script>location = 'http://otherwebsite'</script> is just one naive example.
Ideally you should store the data as-is or use some kind of markup such as (wiki or markdown) to store basic formatting information.
There IS some way to separate the data from the presentation. You keep them separate! If you want to do some formatting on that text that you pulled from the database, go ahead and do that in your application code. Note that structural markup is an entirely different topic from presentation markup (font, color, layout, etc)
http://en.wikipedia.org/wiki/Separation_of_presentation_and_content talks about this very point and makes a clear separation between presentation markup and structural markup in the paragraph under Intended Meaning.
Storing formatting tags in your data generally points to poor separation between the two layers or a data model that isn't sufficient to represent your data properly. As the author is storing data in a database, that might indicate that he has just a single field for holding the "content block" of an article rather than multiple fields for the author, title, body, references, etc. For user input data, we often fall back to a markup inside the user content for designating structure. That happens through "fake" html tags or even real html/xml tags like <h1>, <em>, <a>, etc.
Note that I'm not objecting to structural markup on principle but I would look carefully at why it's required if you're storing it in a database. I am objecting to presentation markup on principle.
It depends on where the data comes in to DB.
If you're the only one who changes the DB content, then it is perfectly normal to store HTML tags in it.
Otherwise, if you store your users input in DB, there are two approaches:
1) To sanitize the input supplied by your users (either on store or on display) to make sure no malicious data will be displayed.
2) To use some intermediate markup language with the limited possibilities (such as BBCode), and to compile it to HTML (again, either on store or on display).
I can not recommend to store any html tags inside your database. In the end you will find yourself lost if your codebase gets bigger and as well if you want to change your html. For example add some arguments to your html tags like classes or similar. You would need to "fix" all the html tags with sql statements. This also counts for the case you want to do something else with your data. For example create RSS Feeds or export it to another format like for example an excel sheet or similar.
Why do you want to do it anyway? I am sure tere is a better solution to your problem.
Try to separate the content form the application layer. Normelize your data and put paragraphs for example in a new dataset. If you really need to for example color one word, I would follow the suggestion that has already been posted. Use some own syntax like [color-a][/color-a]. The export problem could however been solved by striptags()
You can use blob field, however you won't be able to do full searching on it iirc. If you have a column with the template name as a value and a blob with the html template value then this will work out just fine.
IMO it's perfectly fine to store HTML in your database. You sound smart enough to not allow just anything to go into the DB without validation.
You just need to be careful about how it's updated. If you are inserting to the database via code:
INSERT INTO myTable Values(x + y + z)
if the variable x has some HTML in it with single quotes for example, no bueno.
I think the content of the string you stored in database has nothing to do with the presentation layer, its only affection is how your business layer provide the html string (directly read from database or decorate it later) to the presentation layer.

in jqgrid, is there a way to programatically set multi search filter criteria (from the server side of an asp.net-mvc app)

i want to automate a user going into the "Find Records" / multi search UI and preset a filter in jqgrid to
Specific field contains "abc"
Second field does not equal "123"
is this possible in jqgrid? i can set the toolbar filter by just adding item to the query string (Field1="test") so, in my asp.net-mvc controller action, i would do something like this:
string name = "Joe";
return Redirect("/Project?Owner=" + name);
but i now want to replicate the support for the advanced search so i can do
Multiple Fields
Different operator (equals, does not equal)
i would like it to work so if the user did click on the Filter button that it would be prepopualated with these filter just like as if they would have done this initial filter manually like this:
I see this question but i want to be able to do this from the server side. Is there anyway to set postdata from the serverside of any asp.net mvc app??
Presetting of the filter is nothing more as setting pf postData jqGrid parameter. See the old demo (see the answer). If one set search:true the filter will apply (see here and here).
Depend on how you organize you pages it can be very simple to preset the filter property of the postData. You can for example include on the corresponding server generated page the inline <script> which define a global variable with the filter and use it in the grid definition. The filter you can set user depended.
I suggested Tony (see here) to include more support for predefined filters. In my vision if would be nice to predefine some probably complex filters and allow the user choose the filter by name. The way seems me especially good for the corporate clients.

How do I use an enum with custom values for a Sharepoint Web part?

I'm trying to design a Web Part that has a drop-down list for the user to choose from. Eventually, these values will be automatically generated based on some kind of outside data source, so they're going to have somewhat arbitrary numeric values associated with them. This is the code I have now:
public enum filterChoice
{
All=0,
BOCC=12,
Sustainability=15,
Clerk=4,
DA=13,
Emergency=7,
Highlights=3,
POS=6,
PR=1,
PH=5,
SHPR=2,
Test=8,
Transportation=14,
Volunteer=16
};
These are different categories I want the user to choose from. When I choose one and save the settings for my Web Part, Sharepoint is only saving the values in numeric order; that is, All=0, BOCC=1, Sustainability=3 [...] so my Web Part then thinks the user chose the value with the corresponding number (PR when they chose BOCC, Highlights when they chose Sustainability, etc.) How can I make Sharepoint honor my custom values?
Guess you could put only strings in your enumeration and do the translation to the associated numeric values in the code of your webpart using a Dictionary<> or something?

Categories