Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Carlos Mosqueda 240 posts 431 karma points
    May 12, 2020 @ 21:23
    Carlos Mosqueda
    0

    Umbraco 7, Razor, show featured thing of the day

    I have a "featured thing of the day" which is pulled from a list of children of a certain page. I have that.

    My issue is that I need to show one thing of the day. So it has to be the same one for 24 hours or for one day, and then the next day it has to randomly pull a new one the next day.

    How would I do this using Razor? I guess I could do a controller, but I figured Razor in a view would be pretty easy too.

    Any ideas on how to achieve a random pull from a list to pull one node each day?

    My code so far is like this.

    var random = new Random();
    var fCollectList = Umbraco.Content(7471).Descendants("featuredItem");
      int index = random.Next(fCollectList.Count());
    //NEED TO SHOW THE SAME ONE FOR EVERYONE ON A DAY, THEN THE NEXT DAY SHOW ANOTHER RANDOM ONE. 
    <p>@fCollectList[index].Name</p>
    

    Sorry for the fairly newbie question, I know Umbraco fairly well, haven't really done something specificallly like this.

  • Steve Morgan 1346 posts 4453 karma points c-trib
    May 13, 2020 @ 08:42
    Steve Morgan
    0

    Hi,

    I love this idea - it's something that seems very simple but I think is actually non-trivial.

    You need to randomise something but keep that random value for 24 hours - I'm guessing you'd like all users to see the same random article and that you make sure the same one isn't used two days in a row.

    I think you have two or three options

    1. Create a partial that renders a random article, cache this partial for 24 hours (will only work if the app_pool doesn't restart - publishes would also invalidate this)
    2. Get a random article ID and and store as an application variable (along with a datetime when this was first created). Check if this ID is set and the date time is less than 24 hours old - if so use it, if not get one and store the id and datetime.
    3. As 2 but actually store a date time and "featured article" against the root news content node, check this as per 2 but actually call the content service to store this to the umbraco content (note this will create a publish and store the history of the node every day - alternatively you could create a custom DB table to store this in).

    1) and 2) are both possibly going to do what you want but might not be good enough as publishes and site restarts will ruin the 24 hour rule

    If your client isn't too worried about site restarts changing the article the simplest way would be something like:

    <h2>Random article test</h2>
    @{
        int randomArticleId = 0;
        DateTime randomArticleExpires = DateTime.MinValue;
        IPublishedContent randomArticle = null;
    
        // try to get from application session
        if (HttpContext.Current.Application["randomArticleId"] != null && HttpContext.Current.Application["randomArticleExpires"] != null)
        {
            randomArticleId = (int)HttpContext.Current.Application["randomArticleId"];
            randomArticleExpires = (DateTime)HttpContext.Current.Application["randomArticleExpires"];
        }
    
        // if we have an an article id check that it's not "expired"
        if (randomArticleId == 0 || randomArticleExpires < DateTime.Now)
        {
            // change this - was my test data nodes, yours will have a different root id and doctype alias
            var articleRoot = Umbraco.Content(1095);
            var articles = articleRoot.Descendants().Where(x => x.ContentType.Alias == "articlePage" && x.Id != randomArticleId).ToList();
    
            // get a random article
            Random rnd = new Random();
            randomArticle = articles[rnd.Next(articles.Count())];
    
              // remove these lines, just for testing, showing when the article is changed
            <h3>Getting new random @(articles.Count())</h3>
            <h3>Getting new @randomArticle.Id  @@randomArticle.Name</h3>
    
            // store this to the application "session"
            HttpContext.Current.Application["randomArticleId"] = randomArticle.Id;
            HttpContext.Current.Application["randomArticleExpires"] = DateTime.Now.AddSeconds(30);   // for testing change this to .AddDays(1) 
            // HttpContext.Current.Application["randomArticleExpires"] = DateTime.Now.AddDays(1);   
    
        }
        else
        {
            randomArticle = Umbraco.Content(randomArticleId);
        }
    
        <h2>Your random article of the day is: @randomArticle.Id  @randomArticle.Name</h2>
    
    
    }
    

    If you need it to be a hard 24 hours then you will want to use the logic above but store this to the content tree or a custom db table. This logic probably is best done in a controller calling a service too rather than in a Razor view but hopefully it will get you started.

    HTH

    Steve

  • Steve Morgan 1346 posts 4453 karma points c-trib
    May 13, 2020 @ 08:48
    Steve Morgan
    0

    Actually - most sites will restart due to iis recycles so the check of the last article id is likely to fail. If I were you I'd probably create a custom db table and store and retrieve this.

    Steve

Please Sign in or register to post replies

Write your reply to:

Draft