More in this section

Forums / Developing with Sitefinity / Auto link anytime a certain word is used?

Auto link anytime a certain word is used?

10 posts, 0 answered
  1. Aaron
    Aaron avatar
    39 posts
    Registered:
    16 Apr 2009
    04 Nov 2009
    Link to this post
    I know this is more of a general .NET question, however I thought someone could help with some specific instructions using SF Generic content classes.

    Our web site has the need to be able to link certain words to their definition any time that word is used.
    Has anyone implemented this successfully in any .net web application?  and How could this be accomplished in SF? 

    I was thinking a good way would be to created a class that would search each Generic item on page load for the desired keywords and if found would rewrite the HTML as a link of some sort to the definition or at least a popup javascript of definition so that when a user hovered of word it would show definition like  a tool tip.

    Any Ideas?  Maybe there is any easier way, but I have not found any.
  2. Aaron
    Aaron avatar
    39 posts
    Registered:
    16 Apr 2009
    04 Nov 2009
    Link to this post
    I have been working on this today and here is what I have been able to accomplish.  So far the solution I have is unusable because it runs too slow, however its a start.

    this is strictly a javascript solution.

    1. I have a file on the server called test.txt that is my glossary.
    1     ({ 
    2        'term1' : 'definition for term 1', 
    3        'term2' : 'definition for term 2' 
    4     }) 

    2. I use the jquery libraries from http://pupunzi.com/#mb.components/mb.tooltip/tooltip.html

    3. create a web user control called KeyWords.ascx that looks like this.
    1 <%@ Control Language="C#" AutoEventWireup="true" CodeFile="KeyWords.ascx.cs" Inherits="MyControls_Other_KeyWords" %> 
    2 <script type="text/javascript" src="https://www.kedsonline.org/scripts/jquery.min.js"></script> 
    3 <script type="text/javascript" src="https://www.kedsonline.org/scripts/jquery.timers.js"></script> 
    4 <script type="text/javascript" src="https://www.kedsonline.org/scripts/jquery.dropshadow.js"></script> 
    5 <script type="text/javascript" src="https://www.kedsonline.org/scripts/mbTooltip.js"></script> 
    6 <link rel="stylesheet" type="text/css" href="https://www.kedsonline.org/scripts/css/mbTooltip.css" title="style1"  media="screen"
    7  
    8  
    9  
    10  
    11  
    12  
    13 <body> 
    14         <script  type="text/javascript"
    15  
    16       $(function(){ 
    17    
    18  
    19     $.getJSON("/test.txt",function(data) 
    20               {$.each(data, function(i,item) 
    21               {$('p, div, span').each(function ()  
    22 //              {$(this).html($(this).html().replace(new RegExp('('+i+')'), '<href="' + item + '">$1</a>')); 
    23 {$(this).html($(this).html().replace(new RegExp('('+i+')'), '<span style=" background-color:#98BE21;" title="' + item + '" >$1</span>')); 
    24                 }); 
    25             }); 
    26   }); 
    27    
    28  
    29      
    30 $("[title]").mbTooltip({ // also $([domElement]).mbTooltip  >>  in this case only children element are involved 
    31       opacity : .65,       //opacity 
    32       wait:100,           //before show 
    33       cssClass:"default",  // defaultdefault = default 
    34       timePerWord:1200,      //time to show in milliseconds per word 
    35       hasArrow:false,           // if you whant a little arrow on the corner 
    36       hasShadow:true, 
    37       imgPath:"images/", 
    38       anchor:"mouse", //"parent"  you can ancor the tooltip to the mouse position or at the bottom of the element 
    39       shadowColor:"black", //the color of the shadow 
    40       mb_fade:200 //the time to fade-in 
    41         }); 
    42      
    43   }); 
    44    
    45      
    46      
    47      
    48      
    49 </script> 
    50 </body> 


    4. put this control in a page with a Generic content.  the Java script searches for the words from the test.txt, if it finds one it replaces the text with a span element containing the title that holds the keyword definition and when the user hovers over word the tooltip displays the definition.

    this is a test in a plain htm page.  If i put it in a SF it runs 100 times slower.
    http://www.kedsonline.org/test2.htm

    Can anyone improve on what I have so far?
  3. Georgi
    Georgi avatar
    3583 posts
    Registered:
    28 Oct 2016
    05 Nov 2009
    Link to this post
    Hi Aaron,

    I was having a different idea, please check the following forum post - http://www.sitefinity.com/support/forums/sitefinity-3-x/bugs-issues/allow-noscript-tag.aspx#949965

    This way you can perform server side search and replace. For example, when you find "show something" you can replace it with <script>alert('here is something')</script>

    This will most probably cause server load, especially if you do search and replace a lot. In general I believe your approach is a better one.

    Greetings,
    Georgi
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  4. Aaron
    Aaron avatar
    39 posts
    Registered:
    16 Apr 2009
    05 Nov 2009
    Link to this post
    Thanks for replying.   I will mess around with your suggestion today and see how it works, you are probably right, this will put too much of a strain on the server. 

    If it makes it any clearer, the effect I'm wanting is exactly the effect sitefinity has for the help (?) link it puts on the properties of it's controls.  Instead of the showing a popup div on hover I would rather the user click on the keyword to see definition. 

    How can I mimic that effect.  I know it can be done, I have seen it many places. 
    I think instead of a run time solution, I should be focused on searching to replace keywords with code on an indexing time frame.  For instance whenever I updated my glossary I would run a script that would search for my keywords in all text in generic content controls, however I'm not sure how to go about this.

    Any ideas?
  5. SelAromDotNet
    SelAromDotNet avatar
    912 posts
    Registered:
    18 Jul 2012
    06 Nov 2009
    Link to this post
    I suggest that you consider placing the code to regex/replace in an external method on a handler (ashx) and call it using jquery.

    then you could call it on page load something like

    var content = $('.mycontent');
    var newcontent = ajax.load(
    "myhandler.ashx?content=" + content.html());
    content.html(newcontent);

    mind you this is not meant to be cut and pasted; I don't remember offhand the parameters and usage of .load, but if you encode the contents you can pass it through the querystring into the handler, the handler can then run a regex on that based on the input file, and return the encoded content in the response.

    then the javascript just needs to load that response, replacing the text that's there with the new linked text

    I konw i'm off on the exact code to do this (I'm not looking at my jquery cheat sheet), but I think this might work

    hope this was helpful!
  6. Aaron
    Aaron avatar
    39 posts
    Registered:
    16 Apr 2009
    18 Nov 2009
    Link to this post
    Thanks everyone for your suggestions it has helped alot.
    Ok here is what I have come up with so far, but I still need help with some aspects.

    Before I post code, let me describe my current issue. 
    Per your suggestions I am inheriting the InternalPage class to search for keywords and replace html with my custom html to highlight keywords.  The issue is I only want to search for words on specific pages not all pages, How can this be done?  I have part of my method in a Control is there a way to find out if this control is being used before my html replace code is run?  I only want to run the replace html code when I'm using this custom control.

    So here is what I have setup so far. 

    modified: cmsentrypoint.aspx
    <%--<%@ Page Inherits="Telerik.Cms.Web.InternalPage" MasterPageFile="~/Sitefinity/Dummy.master" %>--%> 
     
     
     
    <%@ Page Inherits="Telerik.Samples.InternalPageTweak" MasterPageFile="~/Sitefinity/Dummy.master" %>  
     

    created class InternalPageTweak.cs
    *this code gets my keywords and definitions from a table in db, if html out has keywords, it replaces it with html i need to display popup with definition in javascript. 
    using System; 
    using System.Collections.Generic; 
    using System.Data.SqlClient; 
    using System.Data; 
    using System.Configuration; 
    using System.Web; 
     
    using Telerik.Cms.Web; 
    using System.Web.UI; 
    using System.IO; 
     
    /// <summary>  
    /// Summary description for InternalPageTweak  
    /// </summary>  
    namespace Telerik.Samples 
        public class InternalPageTweak : InternalPage 
        { 
            public InternalPageTweak() 
            { 
                //  
                // TODO: Add constructor logic here  
                //  
            } 
     
     
            protected override void Render(HtmlTextWriter writer) 
            { 
                HtmlTextWriter output = new HtmlTextWriter(new StringWriter()); 
                base.Render(output); 
                string outputString = output.InnerWriter.ToString(); 
                List<Keyword> keywords = new List<Keyword>(); 
           //     if (Telerik.Security.UserManager.GetCurrentUserName().ToLower() == "ajp222") 
         //       { 
                    DataSet myDataSet = getKeywords(); 
                    foreach (DataRow myDataRow in myDataSet.Tables["Keywords"].Rows) 
                    { 
                        keywords.Add(new Keyword(myDataRow["word"].ToString(), myDataRow["definition"].ToString(), myDataRow["url"].ToString())); 
                       // Response.Write(myDataRow["word"].ToString()); 
                    } 
                    keywords.ForEach(delegate(Keyword k) 
                        { 
                            outputString = outputString.Replace(k.word, " <div id=\"definition\" class=\"glossary\"   flag=\"" + k.word + " - " + k.definition + " \" > " + k.word + " </div> "); 
                        }); 
               // } 
     
               writer.Write(outputString); 
            } 
     
     
            protected DataSet getKeywords() 
            { 
     
     
     
                SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Sitefinity"].ConnectionString); 
     
                SqlCommand mySelectCommand = new SqlCommand("Select * from Keywords", connection); 
                SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter(mySelectCommand); 
     
                DataSet myDataSet = new DataSet(); 
                mySqlDataAdapter.Fill(myDataSet, "Keywords"); 
     
     
                connection.Close(); 
     
                return myDataSet; 
            } 
     
     
        } 
     
        public class Keyword 
        { 
     
            public string word; 
            public string definition; 
            public string url; 
     
            public Keyword(string Word, string Definition, string Url) 
            { 
                this.word = Word; 
                this.definition = Definition; 
                this.url = Url; 
            } 
     
        } 

    my custom control named KeyWords.ascx is add to pages i want to highlight keywords, where i use javascript to display keywords popup. *using jquery javascript libraries found here http://craigsworks.com/projects/qtip/
    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="KeyWords.ascx.cs" Inherits="MyControls_Other_KeyWords" %> 
     
     
    <script type="text/javascript" src="/scripts/jquery.qtip-1.0.0-rc3.min.js"></script> 
    <script type="text/javascript" src="/scripts/jquery.qtip-1.0.0-rc3.js"></script> 
     
    <script  type="text/javascript"
     
     
    $(document).ready(function()  
    $('[flag]').each(function() // Select all elements with the "tooltip" attribute 
        $(this).qtip({  
             content:{  
                title: { 
                    text: 'Definition:'// Give the tooltip a title using each elements text 
                    button: 'Close' 
                        }, 
             text:$(this).attr('flag'
             }, 
             hide: 'unfocus'
             style: { 
                tip: true// Apply a speech bubble tip to the tooltip at the designated tooltip corner 
                border: { 
                   width: 0, 
                   radius: 4 
                }, 
                name: 'cream'// Use the default light style 
                width: 400 // Set the tooltip width 
             }, 
     
            show: { 
                when: 'click',  
                solo: true  
            }   
            }); 
        }); 
    }); 
    </script> 
     

    this results in the attached screenshot

    Hope this helps someone and if you have any suggestions on how to only replace html on where I'm using my custom control let me know.



  7. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    18 Nov 2009
    Link to this post
    Hi Aaron,

    Can you take out the logic from the Internal Page class and use it either in the master pages. You can create code files for the master pages that the pages using this control inherit. Then you can override the master page's Render method using the same logic. All ASP.NET pages and controls have Render method that can be overridden in this way. For more information, please read Control.Render Method (System.Web.UI) on MSDN.

    Kind regards,
    Radoslav Georgiev
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  8. Aaron
    Aaron avatar
    39 posts
    Registered:
    16 Apr 2009
    20 Nov 2009
    Link to this post
    Thank you.
    I think that may be exactly what I needed to know. 
    ...working on some other projects at the moment, but I'll try to work with this a  little today and post my results.


  9. Aaron
    Aaron avatar
    39 posts
    Registered:
    16 Apr 2009
    09 Dec 2009
    Link to this post
    Ok I have tried your suggestion and the code works from the masterpage, however I cannont limit where it replaces keyword with custom html.  as of now it finds key words in all output. i.e. menus, links etc... and that messes up page.

    I need to be able to be able to filter the logic to only run for certain controls however, since the logic is in the master page I'm having trouble getting it to find controls in the page.

    This only returns controls in the masterpage, I need it to search for controls in the page.
            foreach (Control c in Page.Controls)
            {
               
            }

    any suggestions?
  10. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    09 Dec 2009
    Link to this post
    Hi Aaron,

    Thank you for getting back to us.

    Now you can get a reference of each CmsPage being displayed from the master page. Then you can get its controls collection:
    Telerik.Cms.Web.CmsPageBase page = this.Page as Telerik.Cms.Web.CmsPageBase;
    Telerik.Cms.ICmsPage cmsPage = page.CmsPage;
    foreach (Telerik.Cms.ICmsWebControl control in cmsPage.Controls)
    {
         
    }

    Then you can check for the certain control type, or the container that holds your control. This way you can exclude for example navigation controls. Samples on how to do this can be found here:
    Finding Controls
    Modifying Controls

    Regards,
    Radoslav Georgiev
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Register for webinar
10 posts, 0 answered