ButterCMS 2.0.2
dotnet add package ButterCMS --version 2.0.2
NuGet\Install-Package ButterCMS -Version 2.0.2
<PackageReference Include="ButterCMS" Version="2.0.2" />
paket add ButterCMS --version 2.0.2
#r "nuget: ButterCMS, 2.0.2"
// Install ButterCMS as a Cake Addin #addin nuget:?package=ButterCMS&version=2.0.2 // Install ButterCMS as a Cake Tool #tool nuget:?package=ButterCMS&version=2.0.2
buttercms-csharp
.NET Standard (2.1) Library for ButterCMS API.
Documentation
For a comprehensive list of examples, check out the API documentation.
Installation
To install ButterCMS, run the following command in the Package Manager Console
PM> Install-Package ButterCMS
The library can also be installed to the project via .NET CLI
dotnet add package ButterCMS
Or by adding the package manually to the project file
<ItemGroup>
<PackageReference Include="ButterCMS" Version="2.0.2" />
</ItemGroup>
Usage
To get started with the Butter API, instantiate the ButterCMSClient with the API key found in the Butter Admin Settings. An optional timeout parameter can be passed as a TimeSpan; the default is 10 seconds.
using ButterCMS;
...
var butterClient = new ButterCMSClient("API KEY");
If the application will be making many Butter API calls, it is recommended to store and re-use the client object.
Each Butter client method has a synchronous version and an asynchronous version. Asynchronous methods are appended with the word "Async".
Preview mode
Preview mode can be used to setup a staging website for previewing content fields or for testing content during local development. To fetch content from preview mode add an additional argument, true
, to the package initialization:
using ButterCMS;
...
bool previewMode = true;
var butterClient = new ButterCMSClient("API KEY", null, 3, null, previewMode);
Sections
Posts
List Posts
Listing posts returns a PostsResponse object. This object consists of a metadata object and IEnumerable<Post>
ListPosts() Parameters
Parameter | Default | Description |
---|---|---|
page(optional) | 1 | Used to paginate through older posts. |
pageSize(optional) | 10 | Used to set the number of blog posts shown per page. |
excludeBody(optional) | false | When true, does not return the full post body. Useful for keeping response size down when showing a list of blog posts. |
authorSlug(optional) | Filter posts by an author’s slug. | |
categorySlug(optional) | Filter posts by a category’s slug. |
Examples
PostsResponse posts = butterClient.ListPosts();
PostsResponse filteredPosts = await butterClient.ListPostsAsync(page: 2, pageSize: 5, excludeBody: true, authorSlug: "alice", categorySlug: "dot-net");
Retrieving a Single Post
Retrieving a single Post will return a PostResponse object. This object consists of a single Post and Post Metadata. Post Metadata offers hints about the Previous and Next posts.
RetrievePost() Parameters
Parameter | Description |
---|---|
slug | The slug of the post to be retrieved. |
Examples
PostResponse controversialPost = butterClient.RetrievePost("tabs-vs-spaces-throwdown");
PostResponse safePost = await butterClient.RetrievePostAsync("puppies-and-kittens");
Searching Posts
Searching posts will return the same object as listing posts, PostsResponse
SearchPosts() Parameters
Parameter | Default | Description |
---|---|---|
query | Search query | |
page(optional) | 1 | Used to paginate through older posts. |
pageSize(optional) | 10 | Used to set the number of blog posts shown per page. |
Examples
PostsResponse posts = butterClient.SearchPosts("spaceships");
PostsResponse caffeinePosts = await butterClient.SearchPostsAsync(query: "coffee", page: 3, pageSize: 5);
Authors
List Authors
Listing Authors returns IEnumerable<Author>
ListAuthors() Parameters
Parameter | Description |
---|---|
includeRecentPosts(optional) | If true, will return the author's recent posts in the response |
Examples
IEnumerable<Author> authors = butterClient.ListAuthors();
IEnumerable<Author> authorsWithPosts = await butterClient.ListAuthorsAsync(includeRecentPosts: true);
Retrieve a Single Author
Retrieving an author returns an Author object
RetrieveAuthor() Parameters
Parameter | Description |
---|---|
authorSlug | The slug of the author to be retrieved. |
includeRecentPosts(optional) | If true, will return the author's recent posts in the response |
Examples
Author sally = butterClient.RetrieveAuthor("sally");
Author tylerAndPosts = await butterClient.RetrieveAuthorAsync(authorSlug: "tyler", includeRecentPosts: true);
Categories
List Categories
Listing Categories returns IEnumerable<Category>
ListCategories() Parameters
Parameter | Description |
---|---|
includeRecentPosts(optional) | If true, will return recent posts along with categories |
Examples
IEnumerable<Category> categories = butterClient.ListCategories();
IEnumerable<Category> categoriesWithPosts = await butterClient.ListCategoriesAsync(includeRecentPosts: true);
Retrieve a Single Category
Retrieving a single category returns Category
RetrieveCategory() Parameters
Parameter | Description |
---|---|
categorySlug | The slug of the category to be retrieved. |
includeRecentPosts(optional) | If true, will return recent posts along with category |
Examples
Category dotnetCategory = butterClient.RetrieveCategory("dotnet");
Category fsharpCategoryWithPosts = await butterClient.RetrieveCategoryAsync(categorySlug: "fsharp", includeRecentPosts: true);
Feeds
Each of the feeds methods returns an XmlDocument.
RSS Feed
Retrieve a fully generated RSS feed for your blog.
Examples
XmlDocument rssFeed = butterClient.GetRSSFeed();
XmlDocument rssFeed = await butterClient.GetRSSFeedAsync();
Atom Feed
Retrieve a fully generated Atom feed for your blog.
Examples
XmlDocument atomFeed = butterClient.GetAtomFeed();
XmlDocument atomFeed = await butterClient.GetAtomFeedAsync();
Sitemap
Retrieve a fully generated sitemap for your blog.
Examples
XmlDocument siteMap = butterClient.GetSitemap();
XmlDocument siteMap = await butterClient.GetSitemapAsync();
Collections
New in version 1.3.0
By the power of .NET generics, Collections can now be deserialized by the library! The former method that would defer deserialization is still available to ease transition.
RetrieveContentFields() Parameters
Parameter | Description |
---|---|
key | String array of the Collection key |
parameterDictionary(optional) | Dictionary of additional parameters, such as "locale" or "preview" |
RetrieveContentFields() Exceptions:
Exception | Description |
---|---|
ContentFieldObjectMismatchException | This exception will be thrown when the library can't fit the returned data into the passed object class. |
Examples
var key = new string[1] { "collection_key" };
var dict = new Dictionary<string, string>()
{
{ "locale", "de" }
};
var teamMembersAndHeadline = butterClient.RetrieveContentFields<TeamMembersHeadline>(key, dict);
** Collection JSON documentation** :
As demonstrated in the Collection documentation, any number of user-defined Collections can be retrieved from the API, these can get complicated in C# and you may choose to handle the response yourself. The RetrieveContentFieldsJSON() method will return the raw JSON response from the Butter API.
RetrieveContentFieldsJSON() Parameters
Parameter | Description |
---|---|
key | String array of the Collection key |
parameterDictionary(optional) | Dictionary of additional parameters, such as "locale" or "preview" |
Examples
var key = new string[1] { "collection_key" };
var dict = new Dictionary<string, string>()
{
{ "locale", "de" }
};
var contentFields = await butterClient.RetrieveContentFieldsJSONAsync(key, dict);
Pages
ButterCMS Pages can be retrieved by first defining the custom Page Type as a class. These custom Page Types are defined in the Butter admin.
List Pages
Listing Pages returns a PagesResponse<T> object. Full API documentation can be found at https://buttercms.com/docs/api/#list-pages-for-a-page-type.
ListPages() Parameters
Parameter | Description |
---|---|
pageType | Desired page type |
parameterDictionary | Dictionary of additional parameters. These options are described in greater detail in the full API documentation. |
ListPages() Exceptions
Exception | Description |
---|---|
PagesObjectMismatchException | This exception will be thrown when the library can't fit the returned data into the passed object class. |
Retrieve a Single Page
Retrieving a single page returns a PageResponse<T> object
RetrievePage() Parameters
Parameter | Description |
---|---|
pageType | Desired page type |
pageSlug | Slug of the desired page |
parameterDictionary | Dictionary of additional parameters |
RetrievePage() Exceptions:
Exception | Description |
---|---|
PagesObjectMismatchException | This exception will be thrown when the library can't fit the returned data into the passed object class. |
Examples
Page Type Definition in the Butter Admin
Controller and ViewModel examples
public namespace HungryDevApp
{
public class RecipePage
{
public string category { get; set; }
public string recipe_name { get; set; }
public string main_ingredient { get; set; }
public double estimated_cooking_time_in_minutes { get; set; }
public string ingredient_list { get; set; }
public string instructions { get; set; }
}
public class RecipesController : Controller
{
[Route(recipes/)]
public virtual ActionResult Index(int page = 1, int pageSize = 10)
{
var butterClient = new ButterCMSClient("API KEY");
var parameterDict = new Dictionary<string, string>()
{
{"page", page.ToString()},
{"page_size", pageSize.ToString()}
};
PagesResponse<RecipePage> recipePages = butterClient.ListPages<RecipePage>("recipe", parameterDict);
var viewModel = new RecipesViewModel();
viewModel.PreviousPageNumber = recipePages.Meta.PreviousPage;
viewModel.NextPageNumber = recipePages.Meta.NextPage;
viewModel.PagesCount = recipePages.Meta.Count;
viewModel.Recipes = new List<RecipeViewModel>();
foreach (Page<RecipePage> recipe in recipePages.Data)
{
RecipeViewModel recipeViewModel = new RecipeViewModel();
recipeViewModel.Category = recipe.Fields.category;
recipeViewModel.RecipeName = recipe.Fields.recipe_name;
recipeViewModel.MainIngredient = recipe.Fields.main_ingredient;
recipeViewModel.EstimatedCookingTimeInMinutes = recipe.Fields.estimated_cooking_time_in_minutes;
recipeViewModel.IngredientList = recipe.Fields.ingredient_list;
recipeViewModel.Instructions = recipe.Fields.instructions;
viewModel.Recipes.Add(recipeViewModel);
}
return View(viewModel);
}
[Route(recipe/{slug})]
public virtual ActionResult Recipe(string slug)
{
var butterClient = new ButterCMSClient("API KEY");
PageResponse<RecipePage> recipe = butterClient.RetrievePage<RecipePage>("recipe", slug);
var viewModel = new RecipeViewModel();
viewModel.Category = recipe.Data.Fields.category;
viewModel.RecipeName = recipe.Data.Fields.recipe_name;
viewModel.MainIngredient = recipe.Data.Fields.main_ingredient;
viewModel.EstimatedCookingTimeInMinutes = recipe.Data.Fields.estimated_cooking_time_in_minutes;
viewModel.IngredientList = recipe.Data.Fields.ingredient_list;
viewModel.Instructions = recipe.Data.Fields.instructions;
return View(viewModel);
}
}
public class RecipesViewModel
{
public List<RecipeViewModel> Recipes { get; set; }
public int? PreviousPageNumber { get; set; }
public int? NextPageNumber { get; set; }
public int PagesCount { get; set; }
}
public class RecipeViewModel
{
public string Category { get; set; }
public string RecipeName { get; set; }
public string MainIngredient { get; set; }
public double EstimatedCookingTimeInMinutes { get; set; }
public string IngredientList { get; set; }
public string Instructions { get; set; }
}
}
Example View usage for ListPages
@using HungryDevApp
@{
Layout = "~/Views/Shared/Layouts/_Layout.cshtml";
}
@model RecipesViewModel
<div>
<a href="/recipes/?page=@{Model.PreviousPageNumber}&pageSize=10">Previous page</a>
<a href="/recipes/?page=@{Model.NextPageNumber}&pageSize=10">Next page</a>
</div>
<div>
<p>@{Model.PagesCount} recipes total</p>
</div>
<div>
<ul>
@foreach(var page in Model.Recipes)
{
<li>
<a href="/recipe/@{page.Slug}">@{page.RecipeName}
</li>
}
</ul>
</div>
Example View usage for RetrievePage
@using HungryDevApp
@{
Layout = "~/Views/Shared/Layouts/_Layout.cshtml";
}
@model RecipeViewModel
<div>
<h2>@{Model.RecipeName}</h2>
<p>Estimated cooking time: @{Model.EstimatedCookingTimeInMinutes} minutes</p>
<h3>Ingredients:</h3>
<p>@{Model.IngredientList}</p>
<h3>Instructions:</h3>
<p>@{Model.Instructions}</p>
</div>
Class Definitions
PostsResponse Class
Property | Type |
---|---|
Meta | PostsMeta |
Data | IEnumerable<Post> |
PostsMeta Class
Property | Type |
---|---|
Count | int |
NextPage | int? |
PreviousPage | int? |
Post Class
Property | Type |
---|---|
Url | string |
Created | DateTime |
Published | DateTime |
Author | Author |
Categories | IEnumerable<Category> |
FeaturedImage | string |
FeaturedImageAlt | string |
Slug | string |
Title | string |
Body | string |
Summary | string |
SeoTitle | string |
MetaDescription | string |
Status | PostStatusEnum |
PostStatusEnum
Constant | Value |
---|---|
Unknown | 0 |
Draft | 1 |
Published | 2 |
PostResponse Class
Property | Type |
---|---|
Meta | PostMeta |
Data | Post |
PostMeta Class
Property | Type |
---|---|
NextPost | PostLight |
PreviousPost | PostLight |
PostLight Class
Property | Type |
---|---|
Slug | string |
Title | string |
FeaturedImage | string |
Author Class
Property | Type |
---|---|
FirstName | string |
LastName | string |
string | |
Slug | string |
Bio | string |
Title | string |
LinkedinUrl | string |
FacebookUrl | string |
InstagramUrl | string |
PinterestUrl | string |
TwitterHandle | string |
ProfileImage | string |
RecentPosts | IEnumerable<Post> |
Category Class
Property | Type |
---|---|
Name | string |
Slug | string |
RecentPosts | IEnumerable<Post> |
PagesResponse Class
Property | Type |
---|---|
Meta | PageMeta |
Data | IEnumerable<Page<T>> |
PageMeta Class
Property | Type |
---|---|
Count | int |
PreviousPage | int? |
NextPage | int? |
PageResponse Class
Property | Type |
---|---|
Data | Page<T> |
Page Class
Property | Type |
---|---|
Slug | string |
Updated | DateTime |
Published | DateTime? |
PageType | string |
Fields | T |
Exceptions
Testing
To run SDK test just simply:
PM> dotnet test
Or use Visual Studio Test Explorer.
InvalidKeyException
The library throws this exception when the Butter API key used to instatiate the client was not valid.
ContentFieldObjectMismatchException
This exception will be thrown when the library can't fit the returned data from a Content Field request into the passed object class.
PagesObjectMismatchException
This exception will be thrown when the library can't fit the returned data from a Pages request into the passed object class.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Newtonsoft.Json (>= 13.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
2.0.2 | 2,963 | 10/25/2023 |
2.0.1 | 215 | 10/13/2023 |
2.0.0 | 417 | 9/12/2023 |
1.4.1 | 7,293 | 5/6/2022 |
1.4.0 | 616 | 5/2/2022 |
1.3.10 | 10,592 | 10/26/2021 |
1.3.9 | 434 | 8/13/2021 |
1.3.8 | 380 | 8/6/2021 |
1.3.7 | 11,059 | 6/22/2020 |
1.3.6 | 1,916 | 4/7/2020 |
1.3.5 | 1,832 | 2/27/2020 |
1.3.4 | 22,420 | 5/15/2018 |
1.3.3 | 2,226 | 3/2/2018 |
1.3.2 | 1,429 | 2/4/2018 |
1.3.1 | 1,012 | 1/29/2018 |
1.3.0 | 1,145 | 12/2/2017 |
1.2.2 | 13,773 | 5/5/2017 |
1.2.1 | 1,068 | 4/26/2017 |
1.2.0 | 1,172 | 3/31/2017 |
1.1.0 | 1,112 | 11/9/2016 |
1.0.0 | 1,107 | 10/11/2016 |
Name is now included in pages