I'm interested in migrating my current wordpress blog into piranha cms, but is there a way to import blog posts and images?
We don鈥檛 have an import function atm, but it would be really interesting to provide. As I鈥檓 not a WP expert I would need some guidance though!
Regards
I'm planning on using the SetupController in the blog template as an example and importing content from an RSS feed from my old blog. Not tried yet, but got high hopes.
I've been working on importing out blog into Piranha and have managed to do it without too many problems. We probably have a few hundred blog posts and I managed to export them from our database and import them into Piranha in under a day. I would imagine the approach I've used would work for any kind of importing as I have separated out the export/import process.
I can upload some sample code next week if anyone would find it useful.
Hi NogginBox,
I've got some very(!) rough and ready code here which should hopefully get you going importing your blog content.
What I did first was to export our blog content into a tab separated file, but you could do this as a CSV, XML, JSON file just as easily. Then I created a RazorPage called "BlogImport" and pasted the code below. Then when you load the page, it will import the content into your blog (I assume the blog is under the /blog URL). It's very simple as I can't post the full import as it's got some company-specific code in, but hopefully it should really help you get going with the import.
public class BlogImportModel : PageModel
{
private readonly IHostingEnvironment _env;
private readonly IApi _api;
public BlogImportModel(IHostingEnvironment env, IApi api)
{
_env = env;
_api = api;
}
public void OnGet()
{
// I exported our blog content as a tab separated file although JSON, csv would also be suitable
var tsv = System.IO.File.ReadAllLines(@"exported-blog-contentblog.tsv");
// Get a list of the blog articles to import
var blogArticles = ImportBlogContent(tsv);
// Get the siteId which the blog is under
var siteId = (_api.Sites.GetDefaultAsync().Result).Id;
// I got this GUID from looking in the database. Get this GUID from the Piranha_Pages where PageTypeId='BlogArchive', do not use the Id in the URL
var blogId = Guid.Parse("B7224068-8FD2-4E0A-A947-4B8C424C71C1");
foreach (var article in blogArticles)
{
// First create the page in the database
var page = BlogPost.CreateAsync(_api).Result;
// Now set the properties
page.BlogId = blogId;
page.Title = article.ArticleTitle;
page.Slug = "/blog/" + article.ArticleUrl;
page.Route = "/blog/" + article.ArticleUrl;
page.Published = DateTime.Now;
page.Id = Guid.NewGuid();
//Add your page blocks here..
page.Blocks.Add(new HtmlBlock()
{
Body = article.ArticleContent
});
page.Category = article.Categories;
// Finally save the page - I had to add the wait for some reason but you may be able to remove it
var result = _api.Posts.SaveAsync(page).Wait(2000);
}
}
private List<BlogArticle> ImportBlogContent(string[] tsvLines)
{
// This takes each column from the tsv and builds up a blogpost.
// I am doing this so I can process/tidy the blog posts before adding to Piranha
// The tsv could easily be csv, json or whatever
var blogContent = new List<BlogArticle>();
foreach (var line in tsvLines)
{
var data = line.Split("\t");
var blogArticle = new BlogArticle()
{
ApplicationName = data[1],
ArticleTitle = data[3],
ArticleUrl = data[4],
ArticleIntroduction = data[5],
ArticleContent = data[6],
ArticleButton = data[7],
ArticleAuthor = data[8],
ArticleHeader = data[9],
ArticleDesktopImage = data[9],
ArticleMobileImage = data[10],
PublishedDate = data[11],
Categories = data[12]
};
blogContent.Add(blogArticle);
}
return blogContent;
}
}
public class BlogArticle
{
// This class is a pre-processor class I use before sending the content over to Piranha. Put your own properties/methods in here
public string ApplicationName { get; set; }
public string ArticleTitle { get; set; }
public string ArticleUrl { get; set; }
public string ArticleIntroduction { get; set; }
public string ArticleContent { get; set; }
public string ArticleButton { get; set; }
public string ArticleAuthor { get; set; }
public string ArticleHeader { get; set; }
public string ArticleDesktopImage { get; set; }
public string ArticleMobileImage { get; set; }
public string PublishedDate { get; set; }
public string Categories { get; set; }
}
Looks good! Just a few comments to improve it further!
blog). This is automatically done in the routing. If you add this to the posts the url will end up /blog/blog/postAlias at the same time redirecting the old permalink to the new one so you don't loose any search engine indexing.Category is mandatory in Piranha. Depending on where you import it from you might want to set an "Uncategorized" category if it's empty in the source data.Great comments @tidyui !
If I get some time next week, I'll try these out and add something into the documentation!
I'm currently in need of extending my cli xml importer to do something like this. I wanna do it without spinning up an aspnet core application to do so. Any suggestions?
After some digging around I managed to come up with a solution that does what I want without having it exposed as an HTTP endpoint. I more or less copy pasted code I found in some tests. It does the job though.
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Piranha;
using Piranha.AttributeBuilder;
using Piranha.Services;
using Piranha.Repositories;
using Piranha.Data.EF.SQLite;
namespace Importer
{
class Program
{
static void Main(string[] args)
{
var builder = new DbContextOptionsBuilder<SQLiteDb>();
builder.UseSqlite("Filename=./piranha.tests.db");
var db = new SQLiteDb(builder.Options);
var factory = new ContentFactory(new ServiceCollection().BuildServiceProvider());
var serviceFactory = new ContentServiceFactory(factory);
var api = new Api(
factory,
new AliasRepository(db),
new ArchiveRepository(db),
new MediaRepository(db),
new PageRepository(db, serviceFactory),
new PageTypeRepository(db),
new ParamRepository(db),
new PostRepository(db, serviceFactory),
new PostTypeRepository(db),
new SiteRepository(db, serviceFactory),
new SiteTypeRepository(db)
);
App.Init(api);
var pageTypeBuilder = new PageTypeBuilder(api)
.AddType(typeof(ProductPage))
.Build();
var site = api.Sites.GetDefaultAsync().Result;
var guid = Guid.NewGuid();
var page = ProductPage.CreateAsync(api).Result;
page.Id = guid;
page.SiteId = site.Id;
page.Title = "ProductSomething";
page.Name = "Something";
page.Description = "Some description";
page.Published = DateTime.Now;
api.Pages.SaveAsync(page).Wait();
var pages = api.Pages.GetAllAsync<ProductPage>().Result;
Console.WriteLine("Just something");
}
}
}
Hey guys,
did your efforts lead to usable code which could be incorporated in #1342 ?
@michaelrall Another issue led us to switch to Wordpress instead of PiranhaCMS. Even though it was very nice to use and extend. I never got further than the aforementioned solution.