Ejemplo n.º 1
0
        private void AddResourceTokens(Web web, LocalizationCollection localizations, FileConnectorBase connector)
        {
            if (localizations != null && localizations.Any())
            {
                //https://github.com/SharePoint/PnP-Provisioning-Schema/issues/301
                //fixing issue to allow multiple resx files in the template. i.e:
                //<pnp:Localization LCID="1033" Name="core" ResourceFile="core.en-us.resx" />
                //<pnp:Localization LCID="3082" Name="core" ResourceFile="core.es-es.resx" />
                //<pnp:Localization LCID="1033" Name="intranet" ResourceFile="intranet.en-us.resx" />
                //<pnp:Localization LCID="3082" Name="intranet" ResourceFile="intranet.es-es.resx" />
                var resourcesFilesCount = localizations.GroupBy(l => l.Name).Count();

                // Read all resource keys in a list
                List <Tuple <string, uint, string> > resourceEntries = new List <Tuple <string, uint, string> >();
                foreach (var localizationEntry in localizations)
                {
                    var filePath = localizationEntry.ResourceFile;
                    using (var stream = connector.GetFileStream(filePath))
                    {
                        if (stream != null)
                        {
#if !NETSTANDARD2_0
                            using (ResXResourceReader resxReader = new ResXResourceReader(stream))
                            {
                                foreach (DictionaryEntry entry in resxReader)
                                {
                                    // One can have multiple resource files in a single file, by adding tokens with resource file name and without we allow both scenarios to resolve
                                    resourceEntries.Add(new Tuple <string, uint, string>($"{localizationEntry.Name}:{entry.Key}", (uint)localizationEntry.LCID, entry.Value.ToString().Replace("\"", "&quot;")));
                                    resourceEntries.Add(new Tuple <string, uint, string>(entry.Key.ToString(), (uint)localizationEntry.LCID, entry.Value.ToString().Replace("\"", "&quot;")));
                                }
                            }
#else
                            var xElement = XElement.Load(stream);
                            foreach (var dataElement in xElement.Descendants("data"))
                            {
                                var key   = dataElement.Attribute("name").Value;
                                var value = dataElement.Value;
                                resourceEntries.Add(new Tuple <string, uint, string>($"{localizationEntry.Name}:{key}", (uint)localizationEntry.LCID, value.ToString().Replace("\"", "&quot;")));
                                resourceEntries.Add(new Tuple <string, uint, string>(key.ToString(), (uint)localizationEntry.LCID, value.ToString().Replace("\"", "&quot;")));
                            }
#endif
                        }
                    }
                }

                var uniqueKeys = resourceEntries.Select(k => k.Item1).Distinct();
                foreach (var key in uniqueKeys)
                {
                    var matches = resourceEntries.Where(k => k.Item1 == key);
                    var entries = matches.Select(k => new ResourceEntry()
                    {
                        LCID = k.Item2, Value = k.Item3
                    }).ToList();
                    LocalizationToken token = new LocalizationToken(web, key, entries);

                    _tokens.Add(token);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Adds a key to be handled by the localization utilities
        /// </summary>
        /// <param name="category">The Token category</param>
        /// <param name="key">The key</param>
        /// <param name="defaultText">The sample content</param>
        public void Localize(string category, string key, string defaultText)
        {
            LocalizationToken token = new LocalizationToken(category, key, defaultText);

            if (!localizationTokens.ContainsKey(category))
            {
                localizationTokens.Add(category, new List <LocalizationToken>());
            }

            localizationTokens[category].Add(token);
        }
Ejemplo n.º 3
0
        public TsCountry(TsMapper mapper, string path)
        {
            _mapper = mapper;
            var file = _mapper.Rfs.GetFileEntry(path);

            if (file == null)
            {
                return;
            }
            LocalizedNames = new Dictionary <string, string>();
            var fileContent = file.Entry.Read();

            var lines = Encoding.UTF8.GetString(fileContent).Split('\n');

            foreach (var line in lines)
            {
                var(validLine, key, value) = SiiHelper.ParseLine(line);
                if (!validLine)
                {
                    continue;
                }

                if (key == "country_data")
                {
                    Token = ScsHash.StringToToken(SiiHelper.Trim(value.Split('.')[2]));
                }
                else if (key == "country_id")
                {
                    CountryId = int.Parse(value);
                }
                else if (key == "name")
                {
                    Name = value.Split('"')[1];
                }
                else if (key == "name_localized")
                {
                    LocalizationToken = value.Split('"')[1];
                    LocalizationToken = LocalizationToken.Replace("@", "");
                }
                else if (key == "country_code")
                {
                    CountryCode = value.Split('"')[1];
                }
                else if (key == "pos")
                {
                    var vector = value.Split('(')[1].Split(')')[0];
                    var values = vector.Split(',');
                    X = float.Parse(values[0], CultureInfo.InvariantCulture);
                    Y = float.Parse(values[2], CultureInfo.InvariantCulture);
                }
            }
        }
Ejemplo n.º 4
0
        private void AddResourceTokens(Web web, LocalizationCollection localizations, FileConnectorBase connector)
        {
            if (localizations != null && localizations.Any())
            {
                // Read all resource keys in a list
                List <Tuple <string, uint, string> > resourceEntries = new List <Tuple <string, uint, string> >();
                foreach (var localizationEntry in localizations)
                {
                    var filePath = localizationEntry.ResourceFile;
                    using (var stream = connector.GetFileStream(filePath))
                    {
                        if (stream != null)
                        {
#if !NETSTANDARD2_0
                            using (ResXResourceReader resxReader = new ResXResourceReader(stream))
#else
                            using (ResourceReader resxReader = new ResourceReader(stream))
#endif
                            {
                                foreach (DictionaryEntry entry in resxReader)
                                {
                                    resourceEntries.Add(new Tuple <string, uint, string>(entry.Key.ToString(), (uint)localizationEntry.LCID, entry.Value.ToString().Replace("\"", "&quot;")));
                                }
                            }
                        }
                    }
                }

                var uniqueKeys = resourceEntries.Select(k => k.Item1).Distinct();
                foreach (var key in uniqueKeys)
                {
                    var matches = resourceEntries.Where(k => k.Item1 == key);
                    var entries = matches.Select(k => new ResourceEntry()
                    {
                        LCID = k.Item2, Value = k.Item3
                    }).ToList();
                    LocalizationToken token = new LocalizationToken(web, key, entries);

                    _tokens.Add(token);
                }
            }
        }
Ejemplo n.º 5
0
        public TokenParser(Web web, ProvisioningTemplate template)
        {
            web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Language);

            _web = web;

            _tokens = new List <TokenDefinition>();

            _tokens.Add(new SiteCollectionToken(web));
            _tokens.Add(new SiteToken(web));
            _tokens.Add(new MasterPageCatalogToken(web));
            _tokens.Add(new SiteCollectionTermStoreIdToken(web));
            _tokens.Add(new KeywordsTermStoreIdToken(web));
            _tokens.Add(new ThemeCatalogToken(web));
            _tokens.Add(new SiteNameToken(web));
            _tokens.Add(new SiteIdToken(web));
            _tokens.Add(new AssociatedGroupToken(web, AssociatedGroupToken.AssociatedGroupType.owners));
            _tokens.Add(new AssociatedGroupToken(web, AssociatedGroupToken.AssociatedGroupType.members));
            _tokens.Add(new AssociatedGroupToken(web, AssociatedGroupToken.AssociatedGroupType.visitors));
            _tokens.Add(new GuidToken(web));
            _tokens.Add(new CurrentUserIdToken(web));
            _tokens.Add(new CurrentUserLoginNameToken(web));
            _tokens.Add(new CurrentUserFullNameToken(web));
            _tokens.Add(new AuthenticationRealmToken(web));

            // Add lists
            web.Context.Load(web.Lists, ls => ls.Include(l => l.Id, l => l.Title, l => l.RootFolder.ServerRelativeUrl));
            web.Context.ExecuteQueryRetry();
            foreach (var list in web.Lists)
            {
                _tokens.Add(new ListIdToken(web, list.Title, list.Id));
                _tokens.Add(new ListUrlToken(web, list.Title, list.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length + 1)));
            }

            if (web.IsSubSite())
            {
                // Add lists from rootweb
                var rootWeb = (web.Context as ClientContext).Site.RootWeb;
                rootWeb.Context.Load(rootWeb.Lists, ls => ls.Include(l => l.Id, l => l.Title, l => l.RootFolder.ServerRelativeUrl));
                rootWeb.Context.ExecuteQueryRetry();
                foreach (var rootList in rootWeb.Lists)
                {
                    // token already there? Skip the list
                    if (web.Lists.FirstOrDefault(l => l.Title == rootList.Title) == null)
                    {
                        _tokens.Add(new ListIdToken(web, rootList.Title, rootList.Id));
                        _tokens.Add(new ListUrlToken(web, rootList.Title, rootList.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length + 1)));
                    }
                }
            }

            // Add ContentTypes
            web.Context.Load(web.ContentTypes, cs => cs.Include(ct => ct.StringId, ct => ct.Name));
            web.Context.ExecuteQueryRetry();
            foreach (var ct in web.ContentTypes)
            {
                _tokens.Add(new ContentTypeIdToken(web, ct.Name, ct.StringId));
            }
            // Add parameters
            foreach (var parameter in template.Parameters)
            {
                _tokens.Add(new ParameterToken(web, parameter.Key, parameter.Value));
            }

            // Add TermSetIds
            TaxonomySession session = TaxonomySession.GetTaxonomySession(web.Context);

            var termStores = session.EnsureProperty(s => s.TermStores);

            foreach (var ts in termStores)
            {
                _tokens.Add(new TermStoreIdToken(web, ts.Name, ts.Id));
            }
            var termStore = session.GetDefaultSiteCollectionTermStore();

            web.Context.Load(termStore);
            web.Context.ExecuteQueryRetry();
            if (!termStore.ServerObjectIsNull.Value)
            {
                web.Context.Load(termStore.Groups,
                                 g => g.Include(
                                     tg => tg.Name,
                                     tg => tg.TermSets.Include(
                                         ts => ts.Name,
                                         ts => ts.Id)
                                     ));
                web.Context.ExecuteQueryRetry();
                foreach (var termGroup in termStore.Groups)
                {
                    foreach (var termSet in termGroup.TermSets)
                    {
                        _tokens.Add(new TermSetIdToken(web, termGroup.Name, termSet.Name, termSet.Id));
                    }
                }
            }

            _tokens.Add(new SiteCollectionTermGroupIdToken(web));
            _tokens.Add(new SiteCollectionTermGroupNameToken(web));

            // Fields
            var fields = web.Fields;

            web.Context.Load(fields, flds => flds.Include(f => f.Title, f => f.InternalName));
            web.Context.ExecuteQueryRetry();
            foreach (var field in fields)
            {
                _tokens.Add(new FieldTitleToken(web, field.InternalName, field.Title));
            }

            // Handle resources
            if (template.Localizations.Any())
            {
                // Read all resource keys in a list
                List <Tuple <string, uint, string> > resourceEntries = new List <Tuple <string, uint, string> >();
                foreach (var localizationEntry in template.Localizations)
                {
                    var filePath = localizationEntry.ResourceFile;
                    using (var stream = template.Connector.GetFileStream(filePath))
                    {
                        if (stream != null)
                        {
                            using (ResXResourceReader resxReader = new ResXResourceReader(stream))
                            {
                                foreach (DictionaryEntry entry in resxReader)
                                {
                                    resourceEntries.Add(new Tuple <string, uint, string>(entry.Key.ToString(), (uint)localizationEntry.LCID, entry.Value.ToString()));
                                }
                            }
                        }
                    }
                }

                var uniqueKeys = resourceEntries.Select(k => k.Item1).Distinct();
                foreach (var key in uniqueKeys)
                {
                    var matches = resourceEntries.Where(k => k.Item1 == key);
                    var entries = matches.Select(k => new ResourceEntry()
                    {
                        LCID = k.Item2, Value = k.Item3
                    }).ToList();
                    LocalizationToken token = new LocalizationToken(web, key, entries);

                    _tokens.Add(token);
                }
            }

            // OOTB Roledefs
            web.EnsureProperty(w => w.RoleDefinitions.Include(r => r.RoleTypeKind));
            foreach (var roleDef in web.RoleDefinitions.AsEnumerable().Where(r => r.RoleTypeKind != RoleType.None))
            {
                _tokens.Add(new RoleDefinitionToken(web, roleDef));
            }

            var sortedTokens = from t in _tokens
                               orderby t.GetTokenLength() descending
                               select t;

            _tokens = sortedTokens.ToList();
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="web">A SharePoint site or subsite</param>
        /// <param name="template">a provisioning template</param>
        public TokenParser(Web web, ProvisioningTemplate template)
        {
            web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Language);

            _web = web;

            _tokens = new List <TokenDefinition>();

            _tokens.Add(new SiteCollectionToken(web));
            _tokens.Add(new SiteCollectionIdToken(web));
            _tokens.Add(new SiteCollectionIdEncodedToken(web));
            _tokens.Add(new SiteToken(web));
            _tokens.Add(new MasterPageCatalogToken(web));
            _tokens.Add(new SiteCollectionTermStoreIdToken(web));
            _tokens.Add(new KeywordsTermStoreIdToken(web));
            _tokens.Add(new ThemeCatalogToken(web));
            _tokens.Add(new WebNameToken(web));
            _tokens.Add(new SiteIdToken(web));
            _tokens.Add(new SiteIdEncodedToken(web));
            _tokens.Add(new SiteOwnerToken(web));
            _tokens.Add(new SiteTitleToken(web));

            _tokens.Add(new AssociatedGroupToken(web, AssociatedGroupToken.AssociatedGroupType.owners));
            _tokens.Add(new AssociatedGroupToken(web, AssociatedGroupToken.AssociatedGroupType.members));
            _tokens.Add(new AssociatedGroupToken(web, AssociatedGroupToken.AssociatedGroupType.visitors));
            _tokens.Add(new GuidToken(web));
            _tokens.Add(new DateNowToken(web));
            _tokens.Add(new CurrentUserIdToken(web));
            _tokens.Add(new CurrentUserLoginNameToken(web));
            _tokens.Add(new CurrentUserFullNameToken(web));
            _tokens.Add(new AuthenticationRealmToken(web));
            _tokens.Add(new HostUrlToken(web));
#if !ONPREMISES
            _tokens.Add(new SiteCollectionConnectedOffice365GroupId(web));
#endif

            AddListTokens(web);
            AddContentTypeTokens(web);

            // Add parameters
            foreach (var parameter in template.Parameters)
            {
                _tokens.Add(new ParameterToken(web, parameter.Key, parameter.Value ?? string.Empty));
            }

            AddTermStoreTokens(web);

#if !ONPREMISES
            AddSiteDesignTokens(web);
            AddSiteScriptTokens(web);
            AddStorageEntityTokens(web);
#endif
            // Fields
            var fields = web.Fields;
            web.Context.Load(fields, flds => flds.Include(f => f.Title, f => f.InternalName));
            web.Context.ExecuteQueryRetry();
            foreach (var field in fields)
            {
                _tokens.Add(new FieldTitleToken(web, field.InternalName, field.Title));
            }

            if (web.IsSubSite())
            {
                // SiteColumns from rootsite
                var rootWeb     = ((ClientContext)web.Context).Site.RootWeb;
                var siteColumns = rootWeb.Fields;
                web.Context.Load(siteColumns, flds => flds.Include(f => f.Title, f => f.InternalName));
                web.Context.ExecuteQueryRetry();
                foreach (var field in siteColumns)
                {
                    _tokens.Add(new FieldTitleToken(rootWeb, field.InternalName, field.Title));
                }
            }

            // Handle resources
            if (template.Localizations.Any())
            {
                // Read all resource keys in a list
                List <Tuple <string, uint, string> > resourceEntries = new List <Tuple <string, uint, string> >();
                foreach (var localizationEntry in template.Localizations)
                {
                    var filePath = localizationEntry.ResourceFile;
                    using (var stream = template.Connector.GetFileStream(filePath))
                    {
                        if (stream != null)
                        {
#if !NETSTANDARD2_0
                            using (ResXResourceReader resxReader = new ResXResourceReader(stream))
#else
                            using (ResourceReader resxReader = new ResourceReader(stream))
#endif
                            {
                                foreach (DictionaryEntry entry in resxReader)
                                {
                                    resourceEntries.Add(new Tuple <string, uint, string>(entry.Key.ToString(), (uint)localizationEntry.LCID, entry.Value.ToString()));
                                }
                            }
                        }
                    }
                }

                var uniqueKeys = resourceEntries.Select(k => k.Item1).Distinct();
                foreach (var key in uniqueKeys)
                {
                    var matches = resourceEntries.Where(k => k.Item1 == key);
                    var entries = matches.Select(k => new ResourceEntry()
                    {
                        LCID = k.Item2, Value = k.Item3
                    }).ToList();
                    LocalizationToken token = new LocalizationToken(web, key, entries);

                    _tokens.Add(token);
                }
            }

            // OOTB Roledefs
            web.EnsureProperty(w => w.RoleDefinitions.Include(r => r.RoleTypeKind, r => r.Name, r => r.Id));
            foreach (var roleDef in web.RoleDefinitions.AsEnumerable().Where(r => r.RoleTypeKind != RoleType.None))
            {
                _tokens.Add(new RoleDefinitionToken(web, roleDef));
            }
            foreach (var roleDef in web.RoleDefinitions)
            {
                _tokens.Add(new RoleDefinitionIdToken(web, roleDef.Name, roleDef.Id));
            }

            // Groups
            web.EnsureProperty(w => w.SiteGroups.Include(g => g.Title, g => g.Id));
            foreach (var siteGroup in web.SiteGroups)
            {
                _tokens.Add(new GroupIdToken(web, siteGroup.Title, siteGroup.Id));
            }
            web.EnsureProperty(w => w.AssociatedVisitorGroup).EnsureProperties(g => g.Id, g => g.Title);
            web.EnsureProperty(w => w.AssociatedMemberGroup).EnsureProperties(g => g.Id, g => g.Title);
            web.EnsureProperty(w => w.AssociatedOwnerGroup).EnsureProperties(g => g.Id, g => g.Title);

            if (!web.AssociatedVisitorGroup.ServerObjectIsNull.Value)
            {
                _tokens.Add(new GroupIdToken(web, "associatedvisitorgroup", web.AssociatedVisitorGroup.Id));
            }
            if (!web.AssociatedMemberGroup.ServerObjectIsNull.Value)
            {
                _tokens.Add(new GroupIdToken(web, "associatedmembergroup", web.AssociatedMemberGroup.Id));
            }
            if (!web.AssociatedOwnerGroup.ServerObjectIsNull.Value)
            {
                _tokens.Add(new GroupIdToken(web, "associatedownergroup", web.AssociatedOwnerGroup.Id));
            }

            // AppPackages tokens
#if !ONPREMISES
            AddAppPackagesTokens(web);
#endif
            var sortedTokens = from t in _tokens
                               orderby t.GetTokenLength() descending
                               select t;

            _tokens = sortedTokens.ToList();
        }
Ejemplo n.º 7
0
        public TsCity(TsMapper mapper, string path)
        {
            _mapper = mapper;
            var file = _mapper.Rfs.GetFileEntry(path);

            if (file == null)
            {
                return;
            }
            LocalizedNames = new Dictionary <string, string>();
            var fileContent = file.Entry.Read();

            var lines       = Encoding.UTF8.GetString(fileContent).Split('\n');
            var offsetCount = 0;

            XOffsets = new List <int>();
            YOffsets = new List <int>();

            foreach (var line in lines)
            {
                var(validLine, key, value) = SiiHelper.ParseLine(line);
                if (!validLine)
                {
                    continue;
                }

                if (key == "city_data")
                {
                    Token = ScsHash.StringToToken(SiiHelper.Trim(value.Split('.')[1]));
                }
                else if (key == "city_name")
                {
                    Name = line.Split('"')[1];
                }
                else if (key == "city_name_localized")
                {
                    LocalizationToken = value.Split('"')[1];
                    LocalizationToken = LocalizationToken.Replace("@", "");
                }
                else if (key == "country")
                {
                    Country = value;
                }
                else if (key.Contains("map_x_offsets[]"))
                {
                    if (++offsetCount > 4)
                    {
                        if (int.TryParse(value, out var offset))
                        {
                            XOffsets.Add(offset);
                        }
                    }
                    if (offsetCount == 8)
                    {
                        offsetCount = 0;
                    }
                }
                else if (key.Contains("map_y_offsets[]"))
                {
                    if (++offsetCount > 4)
                    {
                        if (int.TryParse(value, out var offset))
                        {
                            YOffsets.Add(offset);
                        }
                    }
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="web">A SharePoint site or subsite</param>
        /// <param name="template">a provisioning template</param>
        public TokenParser(Web web, ProvisioningTemplate template)
        {
            web.EnsureProperties(w => w.ServerRelativeUrl, w => w.Language);

            _web = web;

            _tokens = new List <TokenDefinition>();

            _tokens.Add(new SiteCollectionToken(web));
            _tokens.Add(new SiteCollectionIdToken(web));
            _tokens.Add(new SiteToken(web));
            _tokens.Add(new MasterPageCatalogToken(web));
            _tokens.Add(new SiteCollectionTermStoreIdToken(web));
            _tokens.Add(new KeywordsTermStoreIdToken(web));
            _tokens.Add(new ThemeCatalogToken(web));
            _tokens.Add(new SiteNameToken(web));
            _tokens.Add(new SiteIdToken(web));
            _tokens.Add(new SiteOwnerToken(web));
            _tokens.Add(new AssociatedGroupToken(web, AssociatedGroupToken.AssociatedGroupType.owners));
            _tokens.Add(new AssociatedGroupToken(web, AssociatedGroupToken.AssociatedGroupType.members));
            _tokens.Add(new AssociatedGroupToken(web, AssociatedGroupToken.AssociatedGroupType.visitors));
            _tokens.Add(new GuidToken(web));
            _tokens.Add(new DateNowToken(web));
            _tokens.Add(new CurrentUserIdToken(web));
            _tokens.Add(new CurrentUserLoginNameToken(web));
            _tokens.Add(new CurrentUserFullNameToken(web));
            _tokens.Add(new AuthenticationRealmToken(web));

            // Add lists
            AddListTokens(web);
            // Add ContentTypes
            AddContentTypeTokens(web);
            // Add parameters
            foreach (var parameter in template.Parameters)
            {
                _tokens.Add(new ParameterToken(web, parameter.Key, parameter.Value ?? string.Empty));
            }

            // Add TermSetIds
            TaxonomySession session = TaxonomySession.GetTaxonomySession(web.Context);

            var termStores = session.EnsureProperty(s => s.TermStores);

            foreach (var ts in termStores)
            {
                _tokens.Add(new TermStoreIdToken(web, ts.Name, ts.Id));
            }
            var termStore = session.GetDefaultSiteCollectionTermStore();

            web.Context.Load(termStore);
            web.Context.ExecuteQueryRetry();
            if (!termStore.ServerObjectIsNull.Value)
            {
                web.Context.Load(termStore.Groups,
                                 g => g.Include(
                                     tg => tg.Name,
                                     tg => tg.TermSets.Include(
                                         ts => ts.Name,
                                         ts => ts.Id)
                                     ));
                web.Context.ExecuteQueryRetry();
                foreach (var termGroup in termStore.Groups)
                {
                    foreach (var termSet in termGroup.TermSets)
                    {
                        _tokens.Add(new TermSetIdToken(web, termGroup.Name, termSet.Name, termSet.Id));
                    }
                }
            }

            _tokens.Add(new SiteCollectionTermGroupIdToken(web));
            _tokens.Add(new SiteCollectionTermGroupNameToken(web));

            // SiteCollection TermSets, only when we're not working in app-only
            if (!web.Context.IsAppOnly())
            {
                var site = (web.Context as ClientContext).Site;
                var siteCollectionTermGroup = termStore.GetSiteCollectionGroup(site, true);
                web.Context.Load(siteCollectionTermGroup);
                try
                {
                    web.Context.ExecuteQueryRetry();
                    if (null != siteCollectionTermGroup && !siteCollectionTermGroup.ServerObjectIsNull.Value)
                    {
                        web.Context.Load(siteCollectionTermGroup, group => group.TermSets.Include(ts => ts.Name, ts => ts.Id));
                        web.Context.ExecuteQueryRetry();
                        foreach (var termSet in siteCollectionTermGroup.TermSets)
                        {
                            _tokens.Add(new SiteCollectionTermSetIdToken(web, termSet.Name, termSet.Id));
                        }
                    }
                }
                catch (NullReferenceException)
                {
                    // If there isn't a default TermGroup for the Site Collection, we skip the terms in token handler
                }
            }

            // Fields
            var fields = web.Fields;

            web.Context.Load(fields, flds => flds.Include(f => f.Title, f => f.InternalName));
            web.Context.ExecuteQueryRetry();
            foreach (var field in fields)
            {
                _tokens.Add(new FieldTitleToken(web, field.InternalName, field.Title));
            }

            if (web.IsSubSite())
            {
                // SiteColumns from rootsite
                var rootWeb     = (web.Context as ClientContext).Site.RootWeb;
                var siteColumns = rootWeb.Fields;
                web.Context.Load(siteColumns, flds => flds.Include(f => f.Title, f => f.InternalName));
                web.Context.ExecuteQueryRetry();
                foreach (var field in siteColumns)
                {
                    _tokens.Add(new FieldTitleToken(rootWeb, field.InternalName, field.Title));
                }
            }

            // Handle resources
            if (template.Localizations.Any())
            {
                // Read all resource keys in a list
                List <Tuple <string, uint, string> > resourceEntries = new List <Tuple <string, uint, string> >();
                foreach (var localizationEntry in template.Localizations)
                {
                    var filePath = localizationEntry.ResourceFile;
                    using (var stream = template.Connector.GetFileStream(filePath))
                    {
                        if (stream != null)
                        {
                            using (ResXResourceReader resxReader = new ResXResourceReader(stream))
                            {
                                foreach (DictionaryEntry entry in resxReader)
                                {
                                    resourceEntries.Add(new Tuple <string, uint, string>(entry.Key.ToString(), (uint)localizationEntry.LCID, entry.Value.ToString()));
                                }
                            }
                        }
                    }
                }

                var uniqueKeys = resourceEntries.Select(k => k.Item1).Distinct();
                foreach (var key in uniqueKeys)
                {
                    var matches = resourceEntries.Where(k => k.Item1 == key);
                    var entries = matches.Select(k => new ResourceEntry()
                    {
                        LCID = k.Item2, Value = k.Item3
                    }).ToList();
                    LocalizationToken token = new LocalizationToken(web, key, entries);

                    _tokens.Add(token);
                }
            }

            // OOTB Roledefs
            web.EnsureProperty(w => w.RoleDefinitions.Include(r => r.RoleTypeKind, r => r.Name, r => r.Id));
            foreach (var roleDef in web.RoleDefinitions.AsEnumerable().Where(r => r.RoleTypeKind != RoleType.None))
            {
                _tokens.Add(new RoleDefinitionToken(web, roleDef));
            }
            foreach (var roleDef in web.RoleDefinitions)
            {
                _tokens.Add(new RoleDefinitionIdToken(web, roleDef.Name, roleDef.Id));
            }

            // Groups
            web.EnsureProperty(w => w.SiteGroups.Include(g => g.Title, g => g.Id));
            foreach (var siteGroup in web.SiteGroups)
            {
                _tokens.Add(new GroupIdToken(web, siteGroup.Title, siteGroup.Id));
            }
            web.EnsureProperty(w => w.AssociatedVisitorGroup).EnsureProperties(g => g.Id, g => g.Title);
            web.EnsureProperty(w => w.AssociatedMemberGroup).EnsureProperties(g => g.Id, g => g.Title);
            web.EnsureProperty(w => w.AssociatedOwnerGroup).EnsureProperties(g => g.Id, g => g.Title);

            if (!web.AssociatedVisitorGroup.ServerObjectIsNull.Value)
            {
                _tokens.Add(new GroupIdToken(web, "associatedvisitorgroup", web.AssociatedVisitorGroup.Id));
            }
            if (!web.AssociatedMemberGroup.ServerObjectIsNull.Value)
            {
                _tokens.Add(new GroupIdToken(web, "associatedmembergroup", web.AssociatedMemberGroup.Id));
            }
            if (!web.AssociatedOwnerGroup.ServerObjectIsNull.Value)
            {
                _tokens.Add(new GroupIdToken(web, "associatedownergroup", web.AssociatedOwnerGroup.Id));
            }

            // AppPackages tokens
#if !ONPREMISES
            AddAppPackagesTokens(web);
#endif
            var sortedTokens = from t in _tokens
                               orderby t.GetTokenLength() descending
                               select t;

            _tokens = sortedTokens.ToList();
        }