Search code examples
c#razordotnetnuke2sxc

How can I detect and display to editors when an item is shared?


We have a large site and there are a few instances where a single basic content item is shared and re-used on 5 to 12 pages. The site has over 10 editors and at least half of those are infrequent, so not remembering that these items are shared is a repeated problem. They keep changing the content on one page adding specifics that then look weird, broken, or very out of place on one or more other pages.

What I would like to do is add some code to the View that detects the item is shared and then add an indicator. Obviously this would be perfect:

if(Content.IsSharedItem) {
  // add a nice blue, round 2sxc style button with a 
  <i class="fas fa-share-alt"></i>
}

I poked around the API, but beyond writing some LINQ (that could be processor intensive), I haven't spotted any way to implement anything like .IsSharedItem

Any ideas or suggestions? Is there something built-in that I might not be aware of or named in a way that I didn't think to search? Any help would be greatly appreciated. Thank you in advance.

DNN 9.03.02, 2sxc 10.9.1, Content App 3.03


Solution

  • I couldn't see how to get from .Parents() to TabID, so I realized, we are executing in the module, so simply doing Dnn.Module.ModuleSettings["ToSIC_SexyContent_ContentGroupGuid"] gives you what you need. Then DNN has no API way to reverse a ModuleSetting.SettingValue, e.g. there is no GetModulesByModuleSettingValue() type thing. So SQL started to make sense and I did this instead...

    I would be really interested if anyone has ways to improve this. Better query? A way to do it without SQL? Refactor or simplify some things? For example, adding the TabName was an afterthought and probably should have been done in SQL.

    Add this to any Content item View, wrap it in an if(Edit.Enabled) or something so only editors/admins see it.

    @if(Edit.Enabled) {
      @RenderPage("_Shared__ContentGroup-Info.cshtml")
    }
    

    Save this to a filename _Shared__ContentGroup-Tabs.cshtml (above)

    @using System.Data
    @using DotNetNuke.Data
    @using DotNetNuke.Entities.Tabs
    
    @*
        This sub template is intended to
        a) reveal whether or not the Content item is shared and
        b) show links to those pages
    
        Reminder the .Parents("2SexyContent-ContentGroup")..EntityGuid is what is stored in
        Dnn.Module.ModuleSettings["ToSIC_SexyContent_ContentGroupGuid"]
    *@
    
    @{
      string sql = @"
          SELECT DISTINCT TabID
          FROM TabModules
            INNER JOIN ModuleSettings ON TabModules.ModuleID = ModuleSettings.ModuleID
          WHERE ModuleSettings.SettingValue = '{0}'";
      sql = string.Format(sql, Dnn.Module.ModuleSettings["ToSIC_SexyContent_ContentGroupGuid"]);
      IList<int> tabs;
      using (IDataContext db = DataContext.Instance()) {
          tabs = db.ExecuteQuery<int>(CommandType.Text, sql).ToList();
      }
    }
    <pre>
    This Content item is shared to @(tabs.Count - 1) other page(s)
    @foreach(int tabId in tabs
      .Where(t => t != Dnn.Tab.TabID)
    ) {
    <a href="/tabid/@tabId)">@TabController.Instance.GetTab(tabId, Dnn.Portal.PortalId).TabName</a>
    }
    </pre>
    

    Example output: screenclip, example output

    So then, since we already have Bootstrap 4 and Fancybox on the pages, I was able to turn the experiment in to a working UI with about 5 more mins of playing around:

    simple UI implementation demo