{"id":23050838,"url":"https://github.com/geta/geta-optimizely-extensions","last_synced_at":"2025-08-22T22:21:53.825Z","repository":{"id":38359226,"uuid":"336213274","full_name":"Geta/geta-optimizely-extensions","owner":"Geta","description":"A comprehensive list of various extension methods improving your productivity for Optimizely sites.","archived":false,"fork":false,"pushed_at":"2025-02-26T07:16:01.000Z","size":133464,"stargazers_count":0,"open_issues_count":7,"forks_count":0,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-03T03:42:42.325Z","etag":null,"topics":["cms","optimizely"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Geta.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-05T08:43:17.000Z","updated_at":"2025-02-26T07:16:05.000Z","dependencies_parsed_at":"2025-02-26T08:22:16.237Z","dependency_job_id":"e5225ad9-9068-4672-986f-878dddf4e68c","html_url":"https://github.com/Geta/geta-optimizely-extensions","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/Geta/geta-optimizely-extensions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Geta%2Fgeta-optimizely-extensions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Geta%2Fgeta-optimizely-extensions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Geta%2Fgeta-optimizely-extensions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Geta%2Fgeta-optimizely-extensions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Geta","download_url":"https://codeload.github.com/Geta/geta-optimizely-extensions/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Geta%2Fgeta-optimizely-extensions/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271710527,"owners_count":24807684,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-22T02:00:08.480Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cms","optimizely"],"created_at":"2024-12-15T23:38:51.429Z","updated_at":"2025-08-22T22:21:53.800Z","avatar_url":"https://github.com/Geta.png","language":"C#","readme":"# Extensions and helpers library for Optimizely CMS\n\n![Build](http://tc.geta.no/app/rest/builds/buildType:(id:Geta_Extensions_00ci),branch:master/statusIcon)\n[![Platform](https://img.shields.io/badge/Platform-.NET%205-blue.svg?style=flat)](https://msdn.microsoft.com/en-us/library/w0x726c2%28v=vs.110%29.aspx)\n[![Platform](https://img.shields.io/badge/Optimizely-%2012-orange.svg?style=flat)](http://world.episerver.com/cms/)\n\n## Description\n\nOptimizely.Extensions is library with useful extension methods and helpers for Optimizely.\n\n## How to get started?\n\nStart by installing NuGet package:\n\n    Install-Package Geta.Optimizely.Extensions\n\n## Features\n\n### Basics\n\nYou can use the GetChildren and GetPage extension methods to easily fetch pages. They also have generic overloads.\n\n    var startPage = ContentReference.StartPage.GetPage\u003cStartPage\u003e();\n    var sections = ContentReference.StartPage.GetChildren\u003cSectionPage\u003e();\n\n### Filters\n\nYou can use _FilterForDisplay_ to easily filter out pages that the user shouldn't see. Here is an example of how to filter child pages of start page.\n\n    var childPages = ContentReference.StartPage.GetChildren().FilterForDisplay();\n\n\n### MenuList extension for HtmlHelper\n\n_MenuList_ extension method helps to build menus. Extension method requires two parameters - _ContentReference_ of the menu root page and _@helper_ which generates menu item. _MenuList_ uses _FilterForDisplay_ extension method to filter out pages that the user doesn't have access to, are not published and are not visible in menu and that don't have a template.\n\n_MenuList_ extension method has three optional parameters:\n- _includeRoot_ - flag which indicates if root page should be included in menu (default is false)\n- _requireVisibleInMenu_ - flag which indicates if pages should be included only when their property _VisibleInMenu_ is true (default is true)\n- _requirePageTemplate_ - flag which indicates if pages should have templates\n\nBelow is an example how menu can be created for pages under start page.\n\n    @{\n        Func\u003cMenuItem, HelperResult\u003e menuItemTemplate =@\u003cli class=\"@(item.Selected ? \"active\" : null)\"\u003e\n            @Html.PageLink(item.Page)\n        \u003c/li\u003e;\n    }\n\n    \u003cnav id=\"main-nav\" class=\"navigation\" role=\"navigation\"\u003e\n        \u003cul class=\"nav\"\u003e\n            @Html.MenuList(ContentReference.StartPage, MenuItemTemplate)\n        \u003c/ul\u003e\n    \u003c/nav\u003e\n\nOr you can do it inline\n\n    \u003cnav id=\"main-nav\" class=\"navigation\" role=\"navigation\"\u003e\n        \u003cul class=\"nav\"\u003e\n            @Html.MenuList(ContentReference.StartPage,\n                @\u003cli class=\"@(item.Selected ? \"active\" : null)\"\u003e\n                    @Html.PageLink(item.Page)\n                \u003c/li\u003e\n            )\n        \u003c/ul\u003e\n    \u003c/nav\u003e\n\n_MenuList_ creates the list only for one level. For multiple menu levels use _MenuList_ extension in menu item template to generate sub-levels.\n\n    @{\n        Func\u003cMenuItem, HelperResult\u003e subMenuItemTemplate =@\u003cli class=\"@(item.Selected ? \"active\" : null)\"\u003e\n            @Html.PageLink(item.Page)\n        \u003c/li\u003e;\n        Func\u003cMenuItem, HelperResult\u003e menuItemTemplate =@\u003cli class=\"@(item.Selected ? \"active\" : null)\"\u003e\n            @Html.PageLink(item.Page)\n            \u003cul\u003e\n                @Html.MenuList(item.Page.ContentLink, subMenuItemTemplate)\n            \u003c/ul\u003e\n        \u003c/li\u003e;\n    }\n\n    \u003cnav id=\"main-nav\" class=\"navigation\" role=\"navigation\"\u003e\n        \u003cul class=\"nav\"\u003e\n            @Html.MenuList(ContentReference.StartPage, menuItemTemplate)\n        \u003c/ul\u003e\n    \u003c/nav\u003e\n\n### QueryStringBuilder\n\nHere we have an example of using _QueryStringBuilder_ to build a filter URL. This can be useful for lists that have filter functionality or sort functionality. To instantiate _QueryStringBuilder_ _UrlHelper_ extensions are used.\n\n    \u003ca href=\"@Url.QueryBuilder(Context.Request.GetEncodedUrl()).Toggle(\"sort\", \"alphabet\")\"\u003eA-Å\u003c/a\u003e\n\nOutput when URL is: /list\n\n    \u003ca href=\"/list?sort=alphabet\"\u003eA-Å\u003c/a\u003e\n\nOutput when URL is: /list?sort=alphabet\n\n    \u003ca href=\"/list\"\u003eA-Å\u003c/a\u003e\n    \nHere is an example of using _QueryStringBuilder_ to add a segment to a Optimizely page URL. This can be useful for forms if you want to post to a page controller action.\n\n    \u003cform action=\"@Url.QueryBuilder(Model.CurrentPage.ContentLink).AddSegment(\"MyActionName\")\"\u003e\u003c/form\u003e\n    \nOutput when page URL is: /about-us\n\n    \u003cform action=\"/about-us/MyActionName\"\u003e\u003c/form\u003e\n\n### Validation\n\nWe have included a simple validation helper for validating email address' using .NET's built in email validation (which updates together with newer versions/patches for .NET).\n\n    bool isValidEmail = ValidationHelper.IsValidEmail(\"test@example.com\");\n\n### Enum properties\n\nIf you have enum values you want to use in your content types you can use the EnumAttribute to decorate your properties. The values can also be localized.\n\n    [BackingType(typeof(PropertyNumber))]\n    [EnumAttribute(typeof(Priority))]\n    public virtual Priority Priority { get; set; }\n\nCredits: http://world.episerver.com/Blogs/Linus-Ekstrom/Dates/2014/5/Enum-properties-for-EPiServer-75/\n\n### Categories\n\nYou can easily get the child categories of any root category you like (as long as you have it's ID).\n\n    IEnumerable\u003cCategory\u003e categories = Category.GetRoot().ID.GetChildCategories();\n\nWhen you have a CategoryList and want to get strongly typed Category objects back you can use the GetFullCategories() method.\n\n    IEnumerable\u003cCategory\u003e categories = CurrentPage.Category.GetFullCategories();\n\nIf you need to check if the CategoryList has that category you can use the Contains() method.\n\n    bool hasBikes = CurrentPage.Category.Contains(\"bikes\");\n\n### Enumerable extensions\n\nYou can easily check if content references are part of a list using `MemberOf`, `MemberOfAny` or `MemberOfAll`, for example to check if a page has any of the supplied categories:\n\n```\nIEnumerable\u003cContentReference\u003e categories = ...;\nvar pagesWithCat = _contentLoader\n    .GetChildren\u003cICategorizableContent\u003e(contentLink, loaderOptions)\n    .Where(x =\u003e x.Categories.MemberOfAny(categories));\n```\n\n### External/friendly URL\n\nThis can be useful when used together with sharing widgets.\n\n    string fullUrl = CurrentPage.GetFriendlyUrl();\n\n### Singleton page\n\nAllows easily load the page which is a single instance of a type.\n\nLoading the singleton page of a type by a parent _ContentReference_.\n\n    var testPage1 = ContentReference.StartPage.GetSingletonPage\u003cTestPage\u003e();\n\nLoading the singleton page of a type by a parent page.\n\n    var startPage = _contentLoader.Get\u003cStartPage\u003e(ContentReference.StartPage);\n    var testPage2 = startPage.GetSingletonPage\u003cTestPage\u003e();\n\n### Content editor user experience helpers/extensions\n\nSet of extension methods and HTML helpers to improve user experience for content editors. \nThe goal is to reduce the need for \"All properties view\" in the Optimizely edit interface.\n\n### EditButton attribute\n\nAttribute to use on properties that you want to have editable in On Page edit mode. Typical usage is for settings properties or other properties that are normally not rendered in your view. \n\n\t[EditButton(ButtonLabel = \"My property\")] // If you don't supply ButtonLabel, display name of the property will be used instead.\n\tpublic virtual string MyProperty { get; set; }\n\nThe edit button is then rendered in the view, only when page is in edit mode, with EditButtonFor helper:\n\n\t@Html.EditButtonFor(m =\u003e m.MyProperty)\n\nYou can also use the EditButtonsGroup helper to render buttons for all properties marked with the EditButtonAttribute:\n\n\t@Html.EditButtonsGroup() // If view model is IContentData \n\t@Html.EditButtonsGroup(m =\u003e m.CurrentPage) // If view model is page view model\n\nNote: EditButtonsGroup accepts an argument named includeBuiltInProperties (defaults to false) which, if true, also renders buttons for the following built-in properties:\n\t\n\tCategory\n\tSimple address\n\tURLSegment\n\tDisplay in navigation\n\tPublished\n\tUpdate modified date\n\n### EditorHelp attribute\n\nAttribute to use on properties you might want an extended help text for in edit mode.\n\n\t[EditorHelp(\"This is the main content area for blocks. The following block types are supported: My block 1, My block 2.\")]\n\tpublic virtual ContentArea MainContentArea { get;set; }\n\nThe help text is rendered in the view (as ul element) with EditorHelpFor helper:\n\n\t@Html.EditorHelpFor(m =\u003e m.MainContentArea)\n\t@Html.PropertyFor(m =\u003e m.MainContentArea)\n\nYou can also render a help summary for all properties marked with the EditorHelpAttribute:\n\n\t@Html.EditorHelpSummary() // If view model is IContentData\n\t@Html.EditorHelpSummary(m =\u003e m.CurrentPage) // If view model is page view model\n\nPlease note that the buttons and help texts are not styled with any CSS in this package. You will have to do that yourself.\n\n## 🏁 Getting Started\n\n### 📦 Prerequisites\n\nEnsure your system is properly configured to meet all prerequisites for Geta Foundation Core listed [here](https://github.com/Geta/geta-foundation-core#%EF%B8%8F-prerequisites)\n\n### 🐑 Cloning the repository\n\n```bash\n    git clone https://github.com/Geta/geta-optimizely-extensions.git\n    cd geta-optimizely-extensions\n    git submodule update --init\n```\n\n### 🚀 Running with Aspire (Recommended)\n```bash\n    # Windows\n    cd sub/geta-foundation-core/src/Foundation.AppHost\n    dotnet run\n\n    # Linux / MacOS\n    sudo env \"PATH=$PATH\" bash\n    chmod +x sub/geta-foundation-core/src/Foundation/docker/build-script/*.sh\n    cd sub/geta-foundation-core/src/Foundation.AppHost\n    dotnet run\n```\n\n### 🖥️ Running as Standalone\n```bash\n   # Windows\n   cd sub/geta-foundation-core\n   ./setup.cmd\n   cd ../../src/Geta.Optimizely.Extensions.Web\n   dotnet run\n\n   # Linux / MacOS\n   sudo env \"PATH=$PATH\" bash\n   cd sub/geta-foundation-core\n   chmod +x *.sh\n   ./setup.sh\n   cd ../../src/Geta.Optimizely.Extensions.Web\n   dotnet run\n```\n\nIf you run into any issues, check the FAQ section [here](https://github.com/Geta/geta-foundation-web?tab=readme-ov-file#faq) \n\n---\n\nCMS username: admin@example.com\n\nPassword: Episerver123!\n\n## Package maintainer\nhttps://github.com/marisks\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeta%2Fgeta-optimizely-extensions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeta%2Fgeta-optimizely-extensions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeta%2Fgeta-optimizely-extensions/lists"}