0

I have a php implode function to list wordpress custom field keys which works great. The problem is I need to wrap the web urls in an href to make them clickable and can't wrap my head around the function sytnax. The key value is in this format www.site.com, so I had it set up for a single entry like so:

<?php if(get_post_meta($post->ID, 'website', true)): ?>
    <strong>Website:</strong> <a href="http://<?php echo get_post_meta($post->ID, 'website', true); ?>" target="_blank"><?php echo get_post_meta($post->ID, 'website', true); ?></a>
<?php endif; ?>

but now we need to be able to hold multiple entries separated by a comma. Here is the code that works, but does not output a clickable url:

<?php
if( $website = get_post_meta($post->ID, 'website') ):
    $label = count( $website ) > 1 ? 'Websites' : 'Website';
    ?>
    <strong><?php echo $label; ?>:</strong> <?php echo implode( $website, ', ' ); ?><br />
    <?php
endif;
?>

This is what I've been playing with, which is clearly wrong

<?php echo '<a href="http://' . implode('" target="_blank">', $website) . "</a>" . ', '; ?><br />

Even if it did work, it would only output the url, not the text that is linked.

--------------------- EDIT -------------------------

Kai's answer was closest, so I marked it the answer, but it didn't include the label variable. By marrying two of them I came up with this answer which works beautifully

<?php
    if( $website = get_post_meta($post->ID, 'website') ):
        $label = count( $website ) > 1 ? 'Websites' : 'Website';
        $links = array_map(
            function($url) {
                 $url = htmlspecialchars($url);
                 return sprintf ('<a href="http://%s">%s</a>', $url, $url);
            },
            $website);
        ?>
        <strong><?php echo $label; ?>:</strong> <?php echo implode(', ', $links); ?><br />
<?php endif ?>
4

3 回答 3

1
<?php
if( $website = get_post_meta($post->ID, 'website') ):
    $label = count( $website ) > 1 ? 'Websites' : 'Website';
    ?>
    <strong><?php echo $label; ?>:</strong> 
    <?php foreach($website AS $w): ?>
        <a href="<?php echo $w; ?>" target="_blank"><?php echo $w; ?></a> <br />
    <?php endforeach; ?>      
<?php endif; ?>

这假设您的数组中的每个“网站”都是一个完整的有效 url,包括 http://

我认为这里问题的根源是了解implode的作用以及为什么它不能按您想要的方式工作。

编辑:

我明白了,您希望它们位于用逗号分隔的内联列表中。你应该使用 Jon 的方法,因为它会比我在这里建议的更优雅地做你想做的事。

于 2012-10-12T23:57:27.877 回答
0

您需要使用装饰器模式。修改下面的示例以满足您的需求

interface HtmlElementInterface {
    public function getText();
    public function render();
}

class LinkDecorator implements HtmlElementInterface {

    protected $title;
    protected $text;

    public function __construct($text, $title, $renderNow = false) {
        if (!is_string($text) || empty($text)) {
            throw new InvalidArgumentException("The text of the element must be a non-empty string.");
        }
        $this->text = $text;
        $this->title = $title;
        if ($renderNow) {
            echo $this->render();
        }
    }

    public function getText() {
        return $this->text;
    }

    public function render() {
        // do your magic here
        return "<a href='" . $this->text . "'>" . $this->title . "</a>";
    }

}
于 2012-10-13T03:44:18.827 回答
0

您可以以类似于您自己尝试过的方式严重滥用implode并使其发挥作用,但这确实不是一个好主意。

您想要的是从 URL 列表移动到锚标记列表,这可以通过以下方式实现array_map

if ($website = get_post_meta($post->ID, 'website')) {
    $links = array_map(
        function($url) {
             $url = htmlspecialchars($url);
             return sprintf ('<a href="http://%s">%s</a>', $url, $url);
        },
        $website);

    echo implode(', ', $links);
}
于 2012-10-12T23:56:50.540 回答