Adding blogposts with categories/tags programatically

Posted by Community Admin on 04-Aug-2018 11:41

Adding blogposts with categories/tags programatically

All Replies

Posted by Community Admin on 25-May-2011 00:00

I'm trying to programmatically add blog posts complete with categories and tags but i'm coming up against several issues. I have managed to add the blog posts to the database, and the taxa are added, but do not seem to be associated correctly.

In the front end:
the blog post displays in the list of posts, but clicking on the title results in the error:

[NoSuchObjectException: No row for Telerik.Sitefinity.Blogs.Model.BlogPost ('sf_blog_posts') GenericOID@44441b29 BlogPost content_id=35da53b0-fa9e-4862-beb7-8b6f05f8dbd7 NOTRES ]<br>   DynamicModule.ns.Wrapped_OpenAccessBlogProvider_fa5ec75407c547f4bd5e4f613fb812ca.GetItemFromUrl(Type itemType, String url, Boolean published, String& redirectUrl) +351<br>   Telerik.Sitefinity.Modules.GenericContent.ContentManagerBase`1.GetItemFromUrl(Type itemType, String url, Boolean published, String& redirectUrl) +75<br>   Telerik.Sitefinity.Web.UI.ContentUI.ContentView.ResolveDetailItemFromUrl() +240<br>   Telerik.Sitefinity.Web.UI.ContentUI.ContentView.ResolveDetailItem() +750<br>   Telerik.Sitefinity.Web.UI.ContentUI.ContentView.CreateChildControls() +63<br>   System.Web.UI.Control.EnsureChildControls() +102<br>   System.Web.UI.Control.PreRenderRecursiveInternal() +42<br>   System.Web.UI.Control.PreRenderRecursiveInternal() +175<br>   System.Web.UI.Control.PreRenderRecursiveInternal() +175<br>   System.Web.UI.Control.PreRenderRecursiveInternal() +175<br>   System.Web.UI.Control.PreRenderRecursiveInternal() +175<br>   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2496


The categories widget displays the categories, and clicking on the category does display the articles I expect.
The tags widget displays the tags, but clicking on one produces a blank page.

In the backend:
Blog posts are being added in DRAFT status, even though I call Publish() when creating them.
Edit a post, click on publish, get the error message:
    The input sequence contains more than one element
Try to delete the post, get the error message:
    Workflow rules do not allow to delete

What is the correct way of creating blog posts and adding categories and tags? Am I missing some permissions settings?

Thanks

Ryan
var categoryList = new List<Guid>();
foreach (string str2 in strArrays1)
    TaxonomyManager tm = TaxonomyManager.GetManager();
    HierarchicalTaxonomy ct = tm.GetTaxonomies<HierarchicalTaxonomy>().Where(t => t.Name == "Categories").SingleOrDefault();
    if (ct != null)
    
        Guid txid;
        Taxon tx = ct.Taxa.Where(b => b.Title.ToLowerInvariant() == str2.ToLowerInvariant()).FirstOrDefault();
        if (tx == null)
        
            txid = Guid.NewGuid();
            tx = (Taxon)tm.CreateItem(typeof(HierarchicalTaxon), txid);
            tx.Taxonomy = ct;
            tx.Title = str2.ToLowerInvariant();
            tx.Name = str2.ToLower();
            tx.Description = "Represents a blog category";
            tx.UrlName = HttpUtility.UrlEncode(str2.ToLowerInvariant());
            ct.Taxa.Add(tx);
            tm.SaveChanges();
        
        else
        
            txid = tx.Id;
        
        categoryList.Add(txid);
    
 
var keywordList = new List<Guid>();
foreach (string str2 in strArrays1)
    TaxonomyManager tm = TaxonomyManager.GetManager();
    FlatTaxonomy ct = tm.GetTaxonomies<FlatTaxonomy>().Where(t => t.Name == "Tags").SingleOrDefault();
    if (ct != null)
    
        Guid txid;
        Taxon tx = ct.Taxa.Where(b => b.Title.ToLowerInvariant() == str2.ToLowerInvariant()).FirstOrDefault();
        if (tx == null)
        
            txid = Guid.NewGuid();
            tx = (Taxon)tm.CreateItem(typeof(FlatTaxon), txid);
            tx.Taxonomy = ct;
            tx.Title = str2.ToLowerInvariant();
            tx.Name = str2.ToLower();
            tx.Description = "Represents a blog Tag";
            tx.UrlName = HttpUtility.UrlEncode(str2.ToLowerInvariant());
            ct.Taxa.Add(tx);
            tm.SaveChanges();
        
        else
        
            txid = tx.Id;
        
        keywordList.Add(txid);
    
 
 
var parentID = new Guid("79525FB5-AD2D-4931-9055-53382996F186");
var fluent = App.WorkWith();
Guid DynamicGuid = Guid.NewGuid();
var blog = fluent.Blog(parentID)
                            .Get();
fluent.BlogPost().CreateNew()
                            .Do(bp =>
                            
                                bp.Parent = blog;
                                bp.Title = strTitle;
                                bp.Description = strDescription;
                                bp.Content = strBody;
                                bp.DateCreated = dtDateCreated;
                                bp.PublicationDate = dtDateCreated;
                                bp.AllowComments = false;
                                bp.ApproveComments = true;
                                bp.AllowTrackBacks = true;
                                bp.Summary = strDescription;
                                bp.PostRights = PostRights.None;
                                if (categoryList.Count > 0)
                                
                                    foreach (Guid a in categoryList)
                                    
                                        bp.Organizer.AddTaxa("Category", a);
                                    
                                
                                if (keywordList.Count > 0)
                                
                                    foreach (Guid a in keywordList)
                                    
                                        bp.Organizer.AddTaxa("Tags", a);
                                    
                                
                            )
                            .Publish()
                            .SaveChanges();


Posted by Community Admin on 25-May-2011 00:00

Okay, i've figured a couple more things out:
Neither categories nor tags work if there are disallowed characters in the UrlName field - I've been URLEncoding the title to create this field, and it's obviously not correct. If I remove the invlaid characters ("+") then it does display the correct posts.

The error displaying a single blog post is because the link in the title is doubling up the baseUrl - it is looking for:
/news/News/...

How can I fix this?
Thanks
Ryan



Posted by Community Admin on 25-May-2011 00:00

Another thing i've found is that the programmatically added blog posts do not have an id, just a contentid. If I try to set this ID while creating the blogpost, I get the error Change of Identity is not supported.

Posted by Community Admin on 30-May-2011 00:00

Hello Ryan,

Here is a list with all problems you are describing and answer to each item. Most of the problems I did not reproduce while running the sample for creating blog post and assigning a tag/category to it.

Please, can you comment each problem how to reproduce it ?

1)Front end:
the blog post displays in the list of posts, but clicking on the title results in the error:

Not reproduced.

2) "In the backend:
Blog posts are being added in DRAFT status, even though I call Publish() when creating them. "

This is a known issue and it will be and fixed in one of the next internal builds.

3) "Edit a post, click on publish, get the error message:
    The input sequence contains more than one element"

Not reproduced

4) "Try to delete the post, get the error message:
    Workflow rules do not allow to delete"

Not reproduced
. This error appears when the user you use does not have permissions to manage content items through the workflow.

5)
"Neither categories nor tags work if there are disallowed characters in the UrlName field - I've been URLEncoding the title to create this field, and it's obviously not correct. If I remove the invlaid characters ("+") then it does display the correct posts."


Instead of using UrlEncode you can use regular expression to replace not allowed symbols:

const string UrlNameCharsToReplace = @"[^\w\-\!\$\'\(\)\=\@\d_]+";
const string UrlNameReplaceString = "-";


 tx.UrlName = Regex.Replace(str2.ToLowerInvariant(), UrlNameCharsToReplace, UrlNameReplaceString);.


6) "Another thing i've found is that the programmatically added blog posts do not have an id, just a contentid. If I try to set this ID while creating the blogpost, I get the error Change of Identity is not supported."

 
I did not reproduce this problem, I found programmatically added blogs inside the database and they have id set

7) "The categories widget displays the categories, and clicking on the category does display the articles I expect.
The tags widget displays the tags, but clicking on one produces a blank page."

Not reproduced. Can you give more details how to reproduce this problem?



Best wishes,
Milena
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 31-May-2011 00:00

Thanks Milena,

Most of the issues have been sorted out now that the Taxa are being created correctly
1), 3), 4), 5), 7) Resolved when Taxa are created correctly, using the above regex to clean the UrlNames.

2) Resolved by adding bp.ApprovalWorkflowState = "PUBLISHED"

6) contentid is a guid, id is NULL. Still happening, occurs only when creating blogposts programmatically, does not occur using the backend page.

Additional issues:
8) The doubled up page name in the Urls generated for the blog posts is still an issue. The page name is News, seems to be adding the page name twice to the UrlName of the blogpost. Happens on both programmatically added blogposts and using the backend. Is this being pulled from the page name, or is this a hardcoded value in the blogs module?

/news/News/2011/05/31/tough-new-law-on-careless-driving

9) The blog posts are being created with the current datetime, not the supplied value. I'm assuming this is because calling Publish() changes the dates to the current datetime. I've noted that changing the publication_date, date_created and last_modified in the database results in errors in the front end, it is unable to find the blog post unless the current date is used in the URL. This is a major issue because i'm importing about 4 years of daily blog posts.
/news/News/2011/05/31/tough-new-law-on-careless-driving  <=======works
/news/News/2008/08/14/tough-new-law-on-careless-driving  <======= cannot be found

Small issue - bp.AutoGenerateUniqueUrl is documented as "Gets or Sets a value..." but is read-only.

Ryan

Posted by Community Admin on 01-Jun-2011 00:00

Figured out 8), but it is still an issue. The first "news" is the "Default page" that the blog is on, the second "News" is the "Blog Url". I'm unable to add an empty Blog Url field to resolve this as it is a required field.
Is there any reason for requiring both of these fields? Just seems a bit pointless.

Posted by Community Admin on 02-Jun-2011 00:00

Hi Ryan,

 
  About point 9) you can set publication date using for setting publication date:

  var publicaitonDate = DateTime.Now.AddYears(-2); //set date in the past
            fluent.BlogPost()
                .CreateNew()
                .Do(bp =>
               
                    postId = bp.Id;
                    bp.Parent = blog;
                    bp.Title = strTitle;
                    //bp.Description = strDescription;
                    //bp.Content = strBody;
                    bp.DateCreated = publicaitonDate;
                    // bp.PublicationDate = publicaitonDate;
                    bp.AllowComments = false;
                    bp.ApproveComments = true;
                    bp.AllowTrackBacks = true;
                    //bp.Summary = strDescription;
                    //bp.PostRights = PostRights.None;
                    if (categoryList.Count > 0)
                   
                        foreach (Guid a in categoryList)
                       
                            bp.Organizer.AddTaxa("Category", a);
                       
                   
                    if (keywordList.Count > 0)
                   
                        foreach (Guid a in keywordList)
                       
                            bp.Organizer.AddTaxa("Tags", a);
                       
                   
                )
            .Publish()
           .SaveChanges();


            var blogPost = fluent.BlogPost(postId)
                .CheckOut()
                .Do(n => n.PublicationDate = publicaitonDate; n.DateCreated = publicaitonDate; )
                .CheckIn()
                .Publish()
                .Do(n => n.PublicationDate = publicaitonDate; n.DateCreated = publicaitonDate; )
                .SaveChanges();



I will continue to work on point 6) and 8)

Let me know if provided code do not solve issue 9).
Thanks!

Best wishes,
Milena
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 03-Jun-2011 00:00

Hello Ryan,

About 6) Can you send an example how to reproduce this problem ? When the post Id is null?

About 8) As you  figured out the blog post url is formed this way:
 pageTitle/blogTitle/publicationDate/blogPostTitle

There is no way a blog to be created with empty url. The reason for forming the url this way is that blog posts are organized in blogs and blog post's title can't be duplicated in a blog.


Regards,
Milena
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 03-Jun-2011 00:00

Hi Milena
For 6) the code I'm using is the same as in your post above, there is a content_id, but the id is NULL.
I also have a version using the second, bold bit of your code before the SaveChanges() of the first block.

8) is okay now, i think i'm understanding it a little clearer. I'm assuming a use case would be for multiple, aggregated blogs on the same base page.
9) is solved when setting the publication date as in your last post. There must be some caching going on somewhere that stores the old URLs for a while so that it doesn't immediately reflect any changes made in the database.

Thanks for your all help
Ryan

Posted by Community Admin on 09-Jun-2011 00:00

Hello Ryan,

Sorry for delayed response!

About 6) after CreateNew() method of the blogs facade, the blog is assigned with id which happens at provider level and more specifically at DataProviderBase:

     public virtual object CreateItem(Type itemType)
       
            return this.CreateItem(itemType, Guid.NewGuid());
       

See attached screenshot (contains debug information) that there is id of the blog after CreateNew() call. This gets persisted in the database upon SaveChanges() call though.

Let me know if you still experience any issues! Thanks.

All the best,
Milena
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

This thread is closed