Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • John ben 78 posts 293 karma points
    Jun 19, 2017 @ 13:34
    John ben
    0

    Hi. i m trying to turn my website to a multilingual one, i have 3 type of langue( ar,fr,eng)

    my code to change langue:

     @{
                                    var curNode = Umbraco.TypedContent(Model.Content.Id);
                                    string nodeLang = curNode.GetCulture().ToString().Substring(0, 2);
                                    bool hasRel = umbraco.cms.businesslogic.relation.RelationType.GetByAlias("relateDocumentOnCopy").HasRelations(curNode.Id);
    
                                }
    
                                @{var rels = umbraco.cms.businesslogic.relation.RelationType.GetByAlias("relateDocumentOnCopy").GetRelations(curNode.Id);
                                }
                                @foreach (var rel in rels)
                                {
    
                                    var relId = (nodeLang == "ar") ? rel.Child.Id : rel.Parent.Id;
                                    var relNode = Umbraco.Content(relId);
                                    var topNode = Umbraco.TypedContent(relId).AncestorOrSelf(1);
                                    string tnLang = topNode.GetCulture().ToString().Substring(0, 2);
                                    string flagLang = (tnLang == "ar") ? "gb" : tnLang;
    
                                    if (tnLang == "fr")
                                    {
    
                                            <a href="@relNode.Url">Français</a>
    
                                    }
                                    else if(tnLang == "ar")
                                    {
                                            <a href="@relNode.Url">English</a>
                                    }
                                    else
                                    {
                                        <a href="@relNode.Url">Arabic</a>
                                    }
    
                                }
    

    got it from https://our.umbraco.org/forum/extending-umbraco-and-using-the-api/83937-language-selector-for-multilingual-site-using-relate-to-original-when-copying-content the probleme is i have 3 langue but i get just 2 in my rels variable did anyone had the same probleme?

  • John ben 78 posts 293 karma points
    Jun 20, 2017 @ 09:15
    John ben
    0

    anyone?

  • Jesus Sevilla 3 posts 73 karma points
    Jun 20, 2017 @ 10:49
    Jesus Sevilla
    0

    Hello, I do not understand very well how the reportDocumentOnCopy works but I put a possible solution, since I had the same problem to implement 3 languages in Umbraco. The MultiIdioma in the document type is declared as a MultiUrl and the image of the flag of the country as a Media Picker.

    Then, inside Umbraco you link each content with the other language. The flag (if you use) with put it once in the root of each language, is worth.

    I hope I have helped you, sorry for the english.

    @{           var languages = Umbraco.TypedContentAtRoot();
    
                               string imagenUrl = "";
    
                                    MultiUrlPickerState urlPicker = null;
    
                                    if (Model.Content.HasValue("multiIdioma"))
                                    {
                                        urlPicker = Model.Content.GetPropertyValue<MultiUrlPickerState>("multiIdioma");
                                        foreach (var item in urlPicker.Items)
                                        {
                                            var nodoAuxLan = Umbraco.TypedContent(item.NodeId);
                                            var nodoRaiz = Umbraco.TypedContent(nodoAuxLan.AncestorOrSelf(1).Id);
    
                                            if (nodoRaiz.GetPropertyValue("imagenPais") != null)
                                            {
                                                imagenUrl = Umbraco.TypedMedia(nodoRaiz.GetPropertyValue<int>("imagenPais")).Url;
                                            }
    
                                            <li><a href="@item.Url"><img src="@imagenUrl" width="22" height="20" /></a></li>
                                        }
                                    }
                                    else 
                                    {@* Caso para cuando no han insertado ningún idioma *@
                                        foreach (var item in languages)
                                        {
                                            var nodoAux = Umbraco.TypedContent(item.Id);
                                            if (nodoAux.GetPropertyValue("imagenPais") != null)
                                            {
                                                imagenUrl = Umbraco.TypedMedia(nodoAux.GetPropertyValue<int>("imagenPais")).Url;
                                            }
    
                                            if (umbraco.library.GetDictionaryItem("MultiLanguage") != "")
                                            {
                                                <li><a href="@nodoAux.Url"><img src="@imagenUrl" width="22" height="20" /></a></li>
                                            }
                                        }
                                    }
                                }   
    
  • John ben 78 posts 293 karma points
    Jun 20, 2017 @ 11:27
    John ben
    0

    Hi. Thanks for the response, but i m not using flags and i don t know what youu have in ur document type is it a list of url so you can switch language ? but even if it's work you are obliged to return to the first page of ur website so u can switch language no?.

    Best Regards.

  • Jesus Sevilla 3 posts 73 karma points
    Jun 20, 2017 @ 11:40
    Jesus Sevilla
    0

    Hello, it's an internal URL for the content of each language. With this solution, if your page has content linked to the content of another language, clicking will go directly to the same content as the selected language. If you do not have any language linked, go to the first page of the website.

    Greetings.

  • John ben 78 posts 293 karma points
    Jun 20, 2017 @ 12:27
    John ben
    0

    i tried ur solution i did this :

     @{var languages = Umbraco.TypedContentAtRoot();
                            foreach (var item in languages)
                            {
                                var nodoAux = Umbraco.TypedContent(item.Id);
                                <a href="@nodoAux.Url">Switch</a>
                                }
                        }
    

    without using ur documenttype still it just get me to the firstpage did'nt know how u managed to switch and stay in the samepage in ur code if you know what i mean.

  • Jesus Sevilla 3 posts 73 karma points
    Jun 20, 2017 @ 12:51
    Jesus Sevilla
    0

    With this code I manage the navigation of the same content with other languages. You need to create in the document type the type multiIdioma as MultiUrl to be able to assign the content.

    if (Model.Content.HasValue("multiIdioma"))
    {
                                    urlPicker = Model.Content.GetPropertyValue<MultiUrlPickerState>("multiIdioma");
                                    foreach (var item in urlPicker.Items)
                                    {
                                     var nodoAuxLan =  Umbraco.TypedContent(item.NodeId);
     var nodoRaiz =  Umbraco.TypedContent(nodoAuxLan.AncestorOrSelf(1).Id);
                                            if (nodoRaiz.GetPropertyValue("imagenPais") != null)
                                            {
                                     imagenUrl = Umbraco.TypedMedia(nodoRaiz.GetPropertyValue<int>("imagenPais")).Url;
                                            }
    
                                        <li><a href="@item.Url"><img src="@imagenUrl" width="22" height="20" /></a></li>
                                    }
                                }
    

    If you realize, in the code you have put you are pointing at the root, so always take the first page. Look at the image below that is sure to understand better than I. Example of multiIdioma

  • John ben 78 posts 293 karma points
    Jun 20, 2017 @ 13:30
    John ben
    0

    Hi. Thanks dude anyway, but i don't think it can work for me because i m having multilingue with relateDocumentOnCopy and i m using umbraco 7. Best regards.

  • John ben 78 posts 293 karma points
    Jun 20, 2017 @ 13:35
    John ben
    0

    My main probleme is why var rels = umbraco.cms.businesslogic.relation.RelationType.GetByAlias("relateDocumentOnCopy").GetRelations(curNode.Id); Give me only 1 langue when i m not in my defaultCulture

  • Marco Lusini 176 posts 1369 karma points
    Jun 21, 2017 @ 05:05
    Marco Lusini
    1

    I guess that it depends on how relations work: if you copy your node (ar) two times (fr & en), then "ar" gets two relation records... Moreover, "fr" and "en" will have one record each. You can see the relations with the Relation Editor package.

    I can give you an example later, when I get in front of my PC.

  • John ben 78 posts 293 karma points
    Jun 21, 2017 @ 09:25
    John ben
    0

    Thanks Marco, that must be it because i copied from ar two times, well atleast i got the problem still need a solution.

  • Marco Lusini 176 posts 1369 karma points
    Jun 21, 2017 @ 10:08
    Marco Lusini
    0

    OK, my site has a structure like this:

    +Site
    +--+IT (type HomePage)
       +--Page 1 
       +--Page 2
       ...
       +--Page N
    +--+EN (type HomePage)
       +--Page 1
       +--Page 2
       ...
       +--Page N
    +--+FR (type HomePage)
       +--Page 1
       +--Page 2
       ...
       +--Page N
    

    Each localized HomePage has the same DocumentType (HomePage) and has the proper Language set in "Culture and Hostnames". Each node is related to the others via Relate on Copy, so that, e.g., IT is related to EN and FR, EN is related to IT and FR is related to IT. With this structure, the following template will give you the list of other, related, pages in the same order of the localized HomePage (the OrderBy(x => x.AncestorOrSelf("HomePage").SortOrder part).

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    @using System.Globalization;
    @using Umbraco.Core.Services;
    @using Umbraco.Core.Models;
    @using Umbraco.Core;
    @{
        Layout = "Master.cshtml";
    
        HashSet<int> relatedIds = new HashSet<int>();
    
        GetRelatedPages(Model.Content.Id, ref relatedIds);
    
        IEnumerable<IPublishedContent> relatedPages = Umbraco.TypedContent(relatedIds).OrderBy(x => x.AncestorOrSelf("HomePage").SortOrder);
    
    }
    @if (relatedPages.Any())
    {
        <ul>
            @foreach (IPublishedContent page in relatedPages)
            {
                CultureInfo culture = page.GetCulture();
                string ThreeLetterName = culture.ThreeLetterISOLanguageName.ToUpper();
                string TwoLetterName = culture.TwoLetterISOLanguageName.ToLower();
                string NativeName = culture.NativeName.ToFirstUpper();
                if (NativeName.IndexOf('(') > 0)
                {
                    NativeName = NativeName.Substring(0, NativeName.IndexOf('(')).Trim();
                }
                string Current = (page.Id == Model.Content.Id) ? "Current" : "";
                <li><a href="@page.Url"><span lang="@TwoLetterName">@NativeName - @ThreeLetterName</span></a> @Current</li>
            }
        </ul>
    }
    @functions
    {
        public static void GetRelatedPages(int id, ref HashSet<int> Ids)
        {
            IRelationService rs = ApplicationContext.Current.Services.RelationService;
    
            IEnumerable<IRelation> relations = rs.GetByParentOrChildId(id, "relateDocumentOnCopy");
    
            foreach (IRelation rel in relations)
            {
                if (!Ids.Contains(rel.ChildId))
                {
                    Ids.Add(rel.ChildId);
                    GetRelatedPages(rel.ChildId, ref Ids);
                }
                if (!Ids.Contains(rel.ParentId))
                {
                    Ids.Add(rel.ParentId);
                    GetRelatedPages(rel.ParentId, ref Ids);
                }
            }
        }
    }
    
  • Marco Lusini 176 posts 1369 karma points
    Jun 21, 2017 @ 10:19
    Marco Lusini
    0

    I have also written an handler that automatically creates copies of each new page in the appropriate branch of the tree, similar to the package Multi Language tools. To use it just copy the following code to /App_Code/Multilanguage.cs

    using System.Collections.Generic;
    using System.Linq;
    using Umbraco.Core;
    using Umbraco.Core.Events;
    using Umbraco.Core.Models;
    using Umbraco.Core.Services;
    using Umbraco.Web;
    
    namespace MultiLanguage
    {
        public class CreateMultilanguageCopy : ApplicationEventHandler
        {
            protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
            {
                ContentService.Saved += ContentService_Saved; // rasied before the content has been saved.
                base.ApplicationStarted(umbracoApplication, applicationContext);
            }
            private void ContentService_Saved(IContentService sender, SaveEventArgs<IContent> eventArgs)
            {
                IRelationService rs = ApplicationContext.Current.Services.RelationService;
                IContentService cs = ApplicationContext.Current.Services.ContentService;
    
                foreach (var node in eventArgs.SavedEntities)
                {
                    if (node.Level > 1 )
                    {
                        IEnumerable<IRelation> relations = rs.GetByParentOrChildId(node.Id, "relateDocumentOnCopy");
    
                        // If saved node doesn't already have a relation...
                        if (!relations.Any())
                        {
                            int parentId = node.ParentId;
    
                            // Get all nodes related to this node parent.
                            HashSet<int> relatedIds = new HashSet<int>();
                            GetRelatedPages(parentId, ref relatedIds);
                            foreach (int relatedParentId in relatedIds)
                            {
                                if (relatedParentId != parentId)
                                {
                                    cs.Copy(node, relatedParentId, true, false, UmbracoContext.Current.Security.CurrentUser.Id);
                                }
                            }
                        }
                    }
                }
            }
            private static void GetRelatedPages(int id, ref HashSet<int> Ids)
            {
                IRelationService rs = ApplicationContext.Current.Services.RelationService;
    
                IEnumerable<IRelation> relations = rs.GetByParentOrChildId(id, "relateDocumentOnCopy");
    
                foreach (IRelation rel in relations)
                {
                    if (!Ids.Contains(rel.ChildId))
                    {
                        Ids.Add(rel.ChildId);
                        GetRelatedPages(rel.ChildId, ref Ids);
                    }
                    if (!Ids.Contains(rel.ParentId))
                    {
                        Ids.Add(rel.ParentId);
                        GetRelatedPages(rel.ParentId, ref Ids);
                    }
                }
            }
    
        }
    }
    
  • John ben 78 posts 293 karma points
    Jun 21, 2017 @ 10:56
    John ben
    0

    Thanks Marco,

    In ur first solution i get cultureinfo doesn't exist ,so i used your handler i copy past it in my App_Code folder ,but still don t know how to use it , can i have an exemple of how you switch and display ur languages?.

    Best Regards.

  • Marco Lusini 176 posts 1369 karma points
    Jun 21, 2017 @ 11:01
    Marco Lusini
    0

    Before using the Save handler better try by hand (btw, I made a slight change to the handler)...

    The handler simply copies the new pages for you (i.e. if you create a "Page 4" under IT, it copies it under EN and FR, provided that IT, EN and FR are related).

    Did you set the righ Language in "Culture and Hostnames", in the localized Home Pages? What is your structure? Which version of Umbraco do you use? Do you use Model Builder?

    You should really install Relation Editor...

  • John ben 78 posts 293 karma points
    Jun 21, 2017 @ 11:07
    John ben
    0

    My stucture :

    +--+AR (type pagePrincipal)
       +--Page 1 
       +--Page 2
       ...
       +--Page N
    +--+Fr (type pagePrincipal)
       +--Page 1 
       +--Page 2
       ...
       +--Page N
    +--+En(type pagePrincipal)
       +--Page 1 
       +--Page 2
       ...
       +--Page N
    

    my cultures and hostnames are all set i m using umbraco 7.5.9 , my default culture is ar when i used my code above to switch i get this in ar : enter image description here

    and i get in fr and en only : enter image description here

    I tried to install Relation Editor but i get an error in the installation from the developper package.

    My cultures are all set and i don t use a modelbuilder enter image description here

  • Marco Lusini 176 posts 1369 karma points
    Jun 21, 2017 @ 13:41
    Marco Lusini
    1

    Relation Editor must be rebuilt to work with newer Umbraco, you can try with this: Relation editor rebuilt by me. To clarify, the Language is set at the pagePrincipal level? I.E., AR has the "ar-MA" Language, EN has the "en-US" (or "en-UK") language and FR has the "fr-FR"?

  • John ben 78 posts 293 karma points
    Jun 21, 2017 @ 14:18
    John ben
    0

    Hi Marco.

    Yess ,AR has the "ar-MA" Language, EN has the "en-US" (or "en-UK") language and FR has the "fr-FR", i m going to try ur rebuilt version hope it will work,thanks for the help!.

    Best Regards.

  • Marco Lusini 176 posts 1369 karma points
    Jun 21, 2017 @ 14:40
    Marco Lusini
    0

    My Relation Editor build will help you understand what's going on behind the scenes of the Relations, but won't help with the template... Can you post the complete error message that you get?

  • John ben 78 posts 293 karma points
    Jun 21, 2017 @ 15:43
    John ben
    0

    well when i try to install it i clic install package it give me a blank page when i close it , it stops at 40% and stay like that , when i leave no package installed

  • John ben 78 posts 293 karma points
    Jun 21, 2017 @ 15:53
    John ben
    0

    I menaged to install ur rebuilt package i created a relation between my 3 contents well but still nothing new still don't see how to solve this thanks anyway. enter image description here

  • Marco Lusini 176 posts 1369 karma points
    Jun 21, 2017 @ 15:56
    Marco Lusini
    0

    This is strange, my code should work. What is the exact error?

  • John ben 78 posts 293 karma points
    Jun 21, 2017 @ 16:06
    John ben
    0

    did'nt get an error , and nothing changed still have the same probleme with the relations.

  • John ben 78 posts 293 karma points
    Jun 22, 2017 @ 09:39
    John ben
    0

    Hi .

    Managed to get 50% working the module seems to be working but i have a little problem. enter image description here

    but when i get to my view :

    fr is ok , arabe is ok but english i get this :enter image description here

    Best Regards

  • Marco Lusini 176 posts 1369 karma points
    Jun 22, 2017 @ 10:00
    Marco Lusini
    1

    Relation Editor is best used in the content Tree... The first step is to open Section>Document Types, right click on the Document Type for which you want to explore the Relations (i.e. pagePrincipal) and select Enable Relations. After you have enabled Relation Editor for you home type, go in Content section, right click on one of your home nodes, e.g. AR, and you should see an Edit relations option which lets you see the nodes related to AR.

  • John ben 78 posts 293 karma points
    Jun 22, 2017 @ 10:17
    John ben
    0

    already did that Arabe and FR have the same relation of english but not getting the same result . (like in this video https://www.youtube.com/watch?v=xU3ifl_6xtk)

  • Marco Lusini 176 posts 1369 karma points
    Jun 22, 2017 @ 10:40
    Marco Lusini
    1

    This what I see for the IT node in my sample site:enter image description here: IT is related to EN and FR.

    With this setup, GetRelatedPages() returns the set of the three related nodes: {1095 (IT), 1230 (EN), 1306 (FR)} and the rest of the sample does the visualization...

  • John ben 78 posts 293 karma points
    Jun 22, 2017 @ 10:44
    John ben
    0

    Try switching by language you will get my issue.

  • Tom Engan 430 posts 1169 karma points
    Jun 22, 2017 @ 10:49
    Tom Engan
    100

    Seeing you've try my example as a starting point ( https://our.umbraco.org/forum/extending-umbraco-and-using-the-api/83937-language-selector-for-multilingual-site-using-relate-to-original-when-copying-content ), and umbraco.cms.businesslogic.relation.RelationType is obsolete, but what I got to work is at the bottom of the thread (but only tested with two language). Much to read here, but can you use, or try some of this that works for me?

    @inherits Umbraco.Web.Macros.PartialViewMacroPage
    
    @{   
        // RelationService returns relations from published, unpublished and trashed nodes 
        var rs = ApplicationContext.Current.Services.RelationService;
    
        // Gets all relations that are connected to this node copied with "Relate to original"
        var relations = rs.GetByParentOrChildId(Model.Content.Id).Where(r => r.RelationType.Alias == "relateDocumentOnCopy");
    
        // Creates a list of all related node ids of trashed, unpublished and published nodes.
        // Each relation also contain the current node id that will be in that list several times.
        // Distinct filters all the doubles current nodes (but still contains trashed and unpublished nodes)
        var ids = relations.SelectMany(r => new[] { r.ChildId, r.ParentId }).Distinct();
    
        // TypedContent only return published nodes, not unpublished and trashed
        // Select creates a new list that contains the return values for each nodeid when
        // passed through TypedContent (a list of IPublishedContent mixed with null values).
        // All trashed and unpublished id's will be replaced with null, and only the published left.
        // != Model.Content.Id filtered away the current node, only one node pr language left?
        var nodes = ids.Select(n => Umbraco.TypedContent(n)).Where(n => n != null && n.Id != Model.Content.Id);
    
        // Get current node
        var curNode = Umbraco.TypedContent(Model.Content.Id);
    
        // Get language of current node
        string nodeLang = curNode.GetCulture().ToString().Substring(0, 2);
    
        // If nodeLang = "no" then flagcode = "no" else flagcode = "gb" 
        var flagcode = (nodeLang == "no") ? "no" : "gb";
    
        <li class="dropdown" data-dropdown="dropdown">
            <a href="@CurrentPage.AncestorOrSelf(1).Url"><img class="flag flag-@flagcode" /><span class="caret"></span></a>
            <ul class="dropdown-menu" role="menu">
            @{
              flagcode = (nodeLang == "no") ? "gb" : "no"; 
              if (nodes.Any())
              {
                foreach (var node in nodes)
                {
                  @:<li><a href="@node.Url"><img class="flag flag-@flagcode" /> @Html.Raw(Umbraco.GetDictionaryValue("Språk"))</a></li>
                }
              } else {
                int homeid = (nodeLang == "en") ? 1084 : 7705;
                @:<li><a href="@Umbraco.NiceUrl(homeid)"><img class="flag flag-@flagcode" /> @Html.Raw(Umbraco.GetDictionaryValue("Språk"))</a></li>
             }}
            </ul>
        </li>
    }
    
  • John ben 78 posts 293 karma points
    Jun 22, 2017 @ 11:00
    John ben
    1

    Hi.

    Thanks got it working with ur code , i had some issues with the switcher great help from Tom and Marco thanks guys!.

    Best regards.

  • Tom Engan 430 posts 1169 karma points
    Jun 22, 2017 @ 11:46
    Tom Engan
    0

    Nice to hear, and then I suppose the codes work for more than two languages. Yes, the switch was only intended for two languages, with use of if then else logic, and must of course be modified for several languages.

Please Sign in or register to post replies

Write your reply to:

Draft