1-888-365-2779
+1-888-365-2779
Try Now
More in this section

Forums / Developing with Sitefinity / Adding blogposts with categories/tags programatically

Adding blogposts with categories/tags programatically

10 posts, 0 answered
  1. Ian
    Ian avatar
    75 posts
    Registered:
    25 Oct 2010
    25 May 2011
    Link to this post
    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();


  2. Ian
    Ian avatar
    75 posts
    Registered:
    25 Oct 2010
    25 May 2011
    Link to this post
    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



  3. Ian
    Ian avatar
    75 posts
    Registered:
    25 Oct 2010
    25 May 2011
    Link to this post
    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.
  4. Milena
    Milena avatar
    75 posts
    Registered:
    05 Apr 2017
    30 May 2011
    Link to this post
    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
  5. Ian
    Ian avatar
    75 posts
    Registered:
    25 Oct 2010
    31 May 2011
    Link to this post
    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
  6. Ian
    Ian avatar
    75 posts
    Registered:
    25 Oct 2010
    01 Jun 2011
    Link to this post
    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.
  7. Milena
    Milena avatar
    75 posts
    Registered:
    05 Apr 2017
    02 Jun 2011
    Link to this post
    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
  8. Milena
    Milena avatar
    75 posts
    Registered:
    05 Apr 2017
    03 Jun 2011
    Link to this post
    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
  9. Ian
    Ian avatar
    75 posts
    Registered:
    25 Oct 2010
    03 Jun 2011
    Link to this post
    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
  10. Milena
    Milena avatar
    75 posts
    Registered:
    05 Apr 2017
    09 Jun 2011
    Link to this post
    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
10 posts, 0 answered