WordPress.org

Forums

View only domain name for links (17 posts)

  1. chaos_cb7
    Member
    Posted 1 year ago #

    I've been looking for a while but I'm only coming up with link shortners like bit.ly.

    What I'm trying to do is make it so that when I psst links into a post only the domain name is viewable. Currently I have to type out the name and make the text a link manually.

    example post edit:
    http://google.com/blablabla
    http://yahoo.com/blablabla
    http://www.reddit.com/blablabla

    example viewable post:
    Google | Yahoo | Reddit

  2. xennex81
    Member
    Posted 1 year ago #

    A link shortener is a web service that creates url forwards.

    You just want some text manipulation.

    The following will return the links you want:

    function pretty_domain_link($url) {
        preg_match('@^(?:http://)?(?:[^.]+\.)?([^.]+)\.@i', $url, $matches);
        return "<a href=\"$url\">".ucfirst($matches[1])."</a>";
    }

    But if you want to automatically parse and modify the links in your posts, you will need...

    Alright, I am going to assume that you want to just post plaintext urls into your post and have those urls replaced by pretty links.

    This is a function that can replace all plaintext urls with <a href=""></a> hyperlinks.

    function prettify_links($content) {
        $pattern = '@(^|\s|>)(https?://(?:[\w]+\.)?([\w]+)\.(?:[\w]+)(?:/(?:[^\s<]*)?)?)(\s|$|<)@i';
        return preg_replace_callback($pattern,
            function ($matches) {
                return $matches[1]."<a href=\"$matches[2]\">".ucfirst($matches[3])."</a>".$matches[4];
            },
            $content);
    }

    Next we add a content filter for posts:

    add_filter('the_content', 'prettify_links');

    Et voilĂ , all urls that are enclosed in either whitespace or tags get prettified.

    Check my site to see an example. The front page is a mess, but if you scroll down you will see a Test Post. Observe the links. If you then open the Test Post itself in single view, you will see the plain text.

    You can add this code to your theme's functions.php. That is to say, add both the prettify_links function and the add_filter call to that file.

    Give it a try, and tell me what you think.

    It's taken me hours to figure out the regular expression that I needed lol, and it is probably still not perfect, because I am too lazy to think of all the different cases of the characters that are valid in urls.

    Anyway, it will accept the following urls:

    >http://bla.com/bla<
    . http://bla.com/bla . (adding the dots to show the spaces, what I mean is that it is a url enclosed in whitespace)

    which normally translates to
    <p>http://bla.com/bla</p>

    So when you enter a url and WordPress turns it into a paragraph it should always work.

    It will NOT process urls enclosed in anything else (except for newlines and beginning/end of data) so it will not touch anything like "http://bla.com/bla" which would be a case if it was ALREADY a hyperlink.

    It's been fun messing with that code. I hope you enjoy it.

  3. chaos_cb7
    Member
    Posted 1 year ago #

    thats actually worked the best of anything iv gotten from people so far. only thing its not doing is setting up the links in one line. since the links get pasted in with line breaks the links come up like this.

    google
    yahoo
    reddit

    instead of:
    Google | Yahoo | Reddit

    might be able to change this in css im not sure yet

  4. xennex81
    Member
    Posted 1 year ago #

    Alright but that will be a rather specialized use case.

    What is doing the pasting?

    I need to know the exact html markup of those three lines.

    You can change it in CSS perhaps but only if the three lines are already identified with some class or id.

    I'd need to do some second stage to merge the lines.

  5. chaos_cb7
    Member
    Posted 1 year ago #

    well i was able to get it to be on the same line with just:
    ul.catg_list li.ddl a {
    display: inline-block;
    only thing i can't figure out now is how to get the | after each download. is there a way to just put a | in after each link with the php?

  6. xennex81
    Member
    Posted 1 year ago #

    So the links are actually put in special <li> tags?

    No there is no way for that because then you'd end up with

    Google | Yahoo | Reddit |

    You need a second stage, so I need to know the format of the resulting html (before my filter gets applied).

  7. chaos_cb7
    Member
    Posted 1 year ago #

    <li class="ddl">
    
        <a href="http://google.com/blabla"></a>
        <p>
            <a href="http://yahoo.com/blabla"></a>
        </p>
        <p>
            <a href="http://reddit.com/blabla"></a>
        </p>

    that's how the html look. as of right now because of how the first link is not in a <p> it actually gets pushed to the end of the list of links. it still looks alright and isn't really an issue but figured id let you know.

  8. xennex81
    Member
    Posted 1 year ago #

    Okay I may have a foolproof answer for you:

    function prettify_links($content) {
        return preg_replace_callback(
            '@(^|\s|>)(https?://(?:[\w]+?\.)?([\w]+?)\.(?:[\w]+)(?:/(?:[^\s<\]"]+)?)?)@i',
            function ($matches) {
                return $matches[1]."<a href=\"$matches[2]\">".ucfirst($matches[3])."</a>";
            },
            $content
        );
    }
    function remove_p_br($content) {
        return preg_replace(
            '@<p>\s*(<a [^>]+>[^<]*</a>)\s*</p>@i',
            "$1",
            preg_replace('@<br.?.?>@', '', $content)
        );
    }
    function group_a($content) {
        $a = "(<a [^>]+>[^<]*</a>)";
        return preg_replace(
            '@'.$a.'\s*'.$a.'\s*'.$a.'@i',
            "<p>$1 | $2 | $3</p>",
            $content
        );
    }
    function prettify_and_merge($content) {
        preg_match('@^(.*?)(<li class="ddl">.*?</li>)(.*)$@is', $content, $split);
        return count($split) ? $split[1] . group_a(remove_p_br(prettify_links($split[2]))) . $split [3] : $content;
    }
    
    add_filter('the_content', 'prettify_and_merge');

    Alternatively these couple of lines would do as well:

    function prettify_and_merge($content) {
        preg_match('@^(.*?)(<li class="ddl">.*?</li>)(.*)$@is', $content, $split);
        $a = "(<a [^>]+>[^<]*</a>)";
        return count($split) ? $split[1] . preg_replace( '@'.$a.'\s*'.$a.'\s*'.$a.'@i', "<p>$1 | $2 | $3</p>", preg_replace('@<p>\s*(<a [^>]+>[^<]*</a>)\s*</p>@i', "$1", preg_replace('@<br.?.?>@', '', preg_replace_callback('@(^|\s|>)(https?://(?:[\w]+?\.)?([\w]+?)\.(?:[\w]+)(?:/(?:[^\s<\]"]+)?)?)@i', function ($matches) { return $matches[1]."<a href=\"$matches[2]\">".ucfirst($matches[3])."</a>"; }, $split[2])))) . $split [3] : $content;
    }
    add_filter('the_content', 'prettify_and_merge');

    (It's a tad long).

    Give it a try.

  9. chaos_cb7
    Member
    Posted 1 year ago #

    doesn't seem to work. tried going to default theme and disabling all plugins but no good. anything with a ] also gets messed up now
    looks like this now:

    <li class="ddl">
    
        <a href="http://google.com/txsrf">
    
            Google
    
        </a>
        <p>
            <a href="http://yahoo.com/[test"></a>
    
            ].txt.html
    
        </p>
        <a href="http://reddit.to/sdfsfsf">
    
            Reddit
    
        </a>

    i see it working on your site but i can't figure out whats different

  10. chaos_cb7
    Member
    Posted 1 year ago #

    with the help of another guy i got everything working. thanks for the help.

  11. chaos_cb7
    Member
    Posted 1 year ago #

    or so i thought. its not working like it should either

  12. xennex81
    Member
    Posted 1 year ago #

    Hey,

    I didn't really have time for it today. But I suspect you just had to remove one character right. I think I treated ] as a delimiter that could end the url rather than be part of it.

    The string that says \] as part of

    '@(^|\s|>)(https?://(?:[\w]+?\.)?([\w]+?)\.(?:[\w]+)(?:/(?:[^\s<\]"]+)?)?)@i',

    would simply need to be deleted, that's all.

    I've been messing with a way of making this code more functional.

    Currently I have a solution that can concatenate any number of links on one line. It tries to remove <p></p> from around the link, and also remove intermediate <br /> tags. Then it just greedily scans for links and puts them on the same line as per your format.

    It doesn't depend on a <li></li> block. It's actually not all that different from what you have now, except that it doesn't use preg_replace.

    I don't really know what the big difference is. I'm not sure if I could do it with a sophisticated preg_replace. I could try. I'm just messing about with different coding styles for fun.

    I'm not sure if I'd ever use it. But I'm thinking it could be useful to have a way of including footnote links. As in:

    This is some text with a note link[_1_] and as I write on I come across another thing I want to reference[_2_].

    And then down below I put down links like this:

    [_1_] http://wordpress.org/support/topic/view-only-domain-name-for-links?replies=10#post-5551262
    [_2_] http://www.xenhideout.nl

    And then I want it to turn into something like:

    [1] WordPress · [2] Xenhideout

  13. chaos_cb7
    Member
    Posted 1 year ago #

    the code the other guy gave me was completely different and i thought it was working but if i have more then 1 spot in the post where i have links it breaks the code. It seems like your code is also only working on the first set of links and ignores everything else. starting to think this is a lot more complicated then i thought it would be.

  14. xennex81
    Member
    Posted 1 year ago #

    function prettify_links($content) {
        return preg_replace_callback(
            '@(^|\s|>)(https?://(?:[\w]+?\.)?([\w]+?)\.(?:[\w]+)(?:/(?:[^\s<"]+)?)?)@i',
            function ($matches) {
                return $matches[1]."<a href=\"$matches[2]\">".ucfirst($matches[3])."</a>";
            },
            $content);
    }
    function remove_p($content) {
        return preg_replace(
            '@<p>\s*(<a [^>]+>[^<]*</a>)\s*</p>@i',
            "$1",
            $content
        );
    }
    function group_a($content) {
        $a = "(<a [^>]+>[^<]*</a>)";
        $s = '\s*(?:<br.?.?>)?\s*';
        $offset = 0;
        preg_match('@'.$a.'@i', $content, $matches, PREG_OFFSET_CAPTURE, $offset);
        $begin = ""; $links = "";
        if (count($matches)) {
            $numberlinks = 0;
            $offset = $matches[0][1];
            $begin = substr($content, 0, $offset);
            $links = $matches[1][0];
            $offset += strlen($matches[0][0]);
    
            preg_match('@'.$s.$a.'@i', $content, $matches, PREG_OFFSET_CAPTURE, $offset);
            while (count($matches) && $offset == $matches[0][1]) {
                $numberlinks++;
                $links .= " | " . $matches[1][0];
                $offset += strlen($matches[0][0]);
                preg_match('@'.$s.$a.'@i', $content, $matches, PREG_OFFSET_CAPTURE, $offset);
            }
            $links = $numberlinks > 1 ? '<p>' . $links . '</p>' : $links;
            $remainder = substr($content, $offset);
            return $begin . $links . group_a($remainder);
        } else
            return $content;
    }
    function prettify_and_merge($content) {
        return group_a(remove_p(prettify_links($content)));
    }
    
    add_filter('the_content', 'prettify_and_merge');

    This code is way different, it doesn't look at <li></li> tags but it does process all the plaintext urls in the post.

    Didn't know you used more than one of those sections in each post.

  15. chaos_cb7
    Member
    Posted 1 year ago #

    wow that seems to work perfect. only thing iv noticed so far is that if i don't hit enter and move the </li>below the last link is pushes the last link down to a 2nd line when viewing it on the site.

  16. xennex81
    Member
    Posted 1 year ago #

    That's more of a WordPress bug. Because it writes the following line:

    <p>http://wordpress.org/support/topic/view-only-domain-name-for-links?replies=1</li>

    So you can see there is no closing </p> and the (x)html is malformed.

    And my code doesn't match just <p>http://link.com/ when it removes the <p> tags.

    function array_add($a, $b) {
        return array( $a[0] . $b[0], $a[1] + $b[1], $a[2] + $b[2] );
    }
    function group_a($content) {
        $concatlinks = function ($offset) use (&$content, &$concatlinks, &$sa) {
            preg_match($sa, $content, $matches, PREG_OFFSET_CAPTURE, $offset);
            return count($matches) && $offset == $matches[0][1] ?
                array_add(
                    array(" | " . $matches[1][0], 0, 1),
                    $concatlinks($offset + strlen($matches[0][0]))
                ) :
                array("", $offset, 0);
        };
    
        $a = "(<a [^>]+>[^<]*</a>)";
        $s = '\s*(?:<br.?.?>)?\s*';
        $sa = '@'.$s.$a.'@i';
        preg_match('@'.$a.'@i', $content, $matches, PREG_OFFSET_CAPTURE, 0);
        if (count($matches)) {
            $offset = $matches[0][1];
            $begin = substr($content, 0, $offset);
            $links = $matches[1][0];
            $offset += strlen($matches[0][0]);
            list($str, $offset, $numberlinks) = $concatlinks($offset);
            $links .= $str;
            $links = $numberlinks > 1 ? '<p>' . $links . '</p>' : $links;
            $remainder = substr($content, $offset);
            return $begin . $links . group_a($remainder);
        } else
            return $content;
    }

    This is the exact same code, only done with recursive functional programming :P :P :P. The recursive function returns a 3-tuple.

  17. chaos_cb7
    Member
    Posted 1 year ago #

    this helps a lot thanks again i appreciate it

Topic Closed

This topic has been closed to new replies.

About this Topic