简单生活,点滴记录
Eking

首页文章无限加载文章

首先在 functions.php 中加入一段判断 ajax 请求的方法:

function is_ajax()
{
    if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
        if ('xmlhttprequest' == strtolower($_SERVER['HTTP_X_REQUESTED_WITH'])) {
            return true;
        }
    }
    return false;
}

然后在首页模板 index.php 中加入判断,if (is_ajax ()): 则不输出 header footer 等信息。
最后一步,再模板公共 js 文件中加入以下代码:

    var page = 1;
var $body = (window.opera) ? (document.compatMode == "CSS1Compat" ? $('html') : $('body')) : $('html,body');
$('#blog_load_more').click(function(event) {
    $(this).hide();
    $('#spinner').show();
    $.ajax({
        type: 'get',
        url: SITE.default_url + '/page/' + parseInt(page + 1),
        success: function(data, textStatus, XMLHttpRequest) {
            page++;
            $('.w-blog-list').append(data);
            $('#spinner').hide();
            $('#blog_load_more').show();
        },
        error: function(MLHttpRequest, textStatus, errorThrown) {
            $('#spinner').hide();
            $.jGrowl('Network Error');
        }
    });
});</code></pre><p>其中 #blog_load_more 为需要绑定的加载更多按钮,#spinner 为加载过程中的动画,.w-blog-list 为首页文章列表容器。<br>由于 Typecho 并没有 Ajax 钩子函数,所以需要在 functions.php 中加入以下代码:</p><pre><code>function site_data()

{

$array = array(
    'site_url'         =&gt; Helper::options()-&gt;siteUrl,
    'default_url'      =&gt; Helper::options()-&gt;siteUrl . 'index.php',
    'theme_images_url' =&gt; Helper::options()-&gt;themeUrl . '/assets/images/',
);
echo json_encode($array);

}

之后在 footer.php 中引入该数据:

<script type="text/javascript">
var SITE = <?php site_data()?>;
</script>

此处的 SITE 就是一个 JSON 对象,可以直接用了。

WordPress 的 add_filter 很好用,Typecho 也可以实现类似的功能:

比如想把文章中的图片都加上 rel="fancybox" 的属性,WordPress 可能使用的以下方法:

add_filter('the_content', 'fancybox_replace');
function fancybox_replace($content)
{

global $post;
$pattern     = &quot;/&lt;a(.*?)href=('|\&quot;)([^&gt;]*).(bmp|gif|jpeg|jpg|png)('|\&quot;)(.*?)&gt;(.*?)&lt;\/a&gt;/i&quot;;
$replacement = '&lt;a$1href=$2$3.$4$5 target=&quot;_blank&quot; rel=&quot;fancybox&quot;$6&gt;$7&lt;/a&gt;';
$content     = preg_replace($pattern, $replacement, $content);
return $content;

}

Typecho 中可以这么写:

function themeInit($archive)
{

if ($archive-&gt;is('single')) {
    $archive-&gt;content = fancybox_replace($archive-&gt;content);
}

}

获取文章第一张图片

分为 markdown 和 html 两种方式

function get_post_img($archive)
{

$cid = $archive-&gt;cid;
$db = Typecho_Db::get();
$rs = $db-&gt;fetchRow($db-&gt;select('table.contents.text')
                           -&gt;from('table.contents')
                           -&gt;where('cid=?', $cid));
$text = $rs['text'];
if (0 === strpos($text, '')) {
    preg_match('/!\[[^\]]*]\([^\)]*\.(png|jpeg|jpg|gif|bmp)\)/i', $text, $img);
    if (empty($img)) {
        return 'none';
    } else {
        preg_match(&quot;/(?:\()(.*)(?:\))/i&quot;, $img[0], $result);
        $img_url = $result[1];
        return '&lt;img src=&quot;' . $img_url . '&quot;/&gt;';
    }
} else {
    preg_match_all(&quot;/\&lt;img.*?src\=\&quot;(.*?)\&quot;[^&gt;]*&gt;/i&quot;, $text, $img);
    if (empty($img)) {
        return 'none';
    } else {
        $img_url = $img[1][0];
        return '&lt;img src=&quot;' . $img_url . '&quot;/&gt;';
    }
}

}

评论列表加 @

function get_comment_at($coid)
{

$db   = Typecho_Db::get();
$prow = $db-&gt;fetchRow($db-&gt;select('parent')-&gt;from('table.comments')
                             -&gt;where('coid = ? AND status = ?', $coid, 'approved'));
$parent = $prow['parent'];
if ($parent != &quot;0&quot;) {
    $arow = $db-&gt;fetchRow($db-&gt;select('author')-&gt;from('table.comments')
                                 -&gt;where('coid = ? AND status = ?', $parent, 'approved'));
    $author = $arow['author'];
    $href   = '&lt;a href=&quot;#comment-' . $parent . '&quot;&gt;@' . $author . '&lt;/a&gt;';
    echo $href;
} else {
    echo '';
}

}

非插件实现文章阅读次数统计

在文章页面引入 get_post_view () 方法。

//get_post_view($this)
function get_post_view($archive)
{

$cid    = $archive-&gt;cid;
$db     = Typecho_Db::get();
$prefix = $db-&gt;getPrefix();
if (!array_key_exists('views', $db-&gt;fetchRow($db-&gt;select()-&gt;from('table.contents')))) {
    $db-&gt;query('ALTER TABLE `' . $prefix . 'contents` ADD `views` INT(10) DEFAULT 0;');
    echo 0;
    return;
}
$row = $db-&gt;fetchRow($db-&gt;select('views')-&gt;from('table.contents')-&gt;where('cid = ?', $cid));
if ($archive-&gt;is('single')) {
   $db-&gt;query($db-&gt;update('table.contents')-&gt;rows(array('views' =&gt; (int) $row['views'] + 1))-&gt;where('cid = ?', $cid));
}
echo $row['views'];

}

判断移动端访问

function is_mobile()
{

$user_agent     = $_SERVER['HTTP_USER_AGENT'];
$mobile_browser = array(
    &quot;mqqbrowser&quot;, //手机QQ浏览器
    &quot;opera mobi&quot;, //手机opera
    &quot;juc&quot;, &quot;iuc&quot;, //uc浏览器
    &quot;fennec&quot;, &quot;ios&quot;, &quot;applewebKit/420&quot;, &quot;applewebkit/525&quot;, &quot;applewebkit/532&quot;, &quot;ipad&quot;, &quot;iphone&quot;, &quot;ipaq&quot;, &quot;ipod&quot;,
    &quot;iemobile&quot;, &quot;windows ce&quot;, //windows phone
    &quot;240x320&quot;, &quot;480x640&quot;, &quot;acer&quot;, &quot;android&quot;, &quot;anywhereyougo.com&quot;, &quot;asus&quot;, &quot;audio&quot;, &quot;blackberry&quot;,
    &quot;blazer&quot;, &quot;coolpad&quot;, &quot;dopod&quot;, &quot;etouch&quot;, &quot;hitachi&quot;, &quot;htc&quot;, &quot;huawei&quot;, &quot;jbrowser&quot;, &quot;lenovo&quot;,
    &quot;lg&quot;, &quot;lg-&quot;, &quot;lge-&quot;, &quot;lge&quot;, &quot;mobi&quot;, &quot;moto&quot;, &quot;nokia&quot;, &quot;phone&quot;, &quot;samsung&quot;, &quot;sony&quot;,
    &quot;symbian&quot;, &quot;tablet&quot;, &quot;tianyu&quot;, &quot;wap&quot;, &quot;xda&quot;, &quot;xde&quot;, &quot;zte&quot;,
);
$is_mobile = false;
foreach ($mobile_browser as $device) {
    if (stristr($user_agent, $device)) {
        $is_mobile = true;
        break;
    }
}
return $is_mobile;

}

ajax 评论

AjaxComments 有小 bug,不太好用,直接使用以下的修改版代码,在公共 js 中调用 ajaxComments () 方法即可

function ajaxComment() {

var selector = {
    commentMainFrame: '#comment',
    commentList: '#commentlist',
    commentNumText: '#comment h3',
    commentReplyButton: '#comment span.reply',
    submitForm: '#commentform',
    submitTextarea: '#textarea',
    submitButton: '#submit',
};
var parentId = '';
bindCommentReplyButton();
$(selector.submitTextarea).after('&lt;div style=&quot;display:none;&quot; id=&quot;ajaxCommentMsg&quot;&gt;&lt;\/div&gt;');
$msg = $('#ajaxCommentMsg');
$(document).on('submit', selector.submitForm, function() {
    $msg.empty();
    $(selector.submitButton).val('发射中哦=A=');
    $(selector.submitButton).attr('disabled', true).fadeTo('slow', 0.5);
    if ($(selector.submitForm).find('#author')[0]) {
        if ($(selector.submitForm).find('#author').val() == '') {
            message('昵称没填呢QAQ');
            enableCommentButton();
            return false;
        }
        if ($(selector.submitForm).find('#mail').val() == '') {
            message('邮箱没填呢QAQ');
            enableCommentButton();
            return false;
        }
        var filter = /^[^@\s&lt;&amp;&gt;]+@([a-z0-9]+\.)+[a-z]{2,4}$/i;
        if (!filter.test($(selector.submitForm).find('#mail').val())) {
            message('邮箱地址不正确呢QAQ');
            enableCommentButton();
            return false;
        }
    }
    if ($(selector.submitForm).find(selector.submitTextarea).val() == '') {
        message('评论似乎什么也没写呢QAQ');
        enableCommentButton();
        return false;
    }
    $.ajax({
        url: $(this).attr('action'),
        type: $(this).attr('method'),
        data: $(this).serializeArray(),
        error: function() {
            message('发射失败,请重试!');
            setTimeout(NProgress.done, 500)
            enableCommentButton();
            return false;
        },
        success: function(data) {
            if (!$(selector.commentList, data).length) {
                errorMsg = data.match(/.+/g).join().match(/\&lt;div.+\&gt;.+\&lt;\/div\&gt;/g).join().match(/[^\,]+/g);
                $msg.html(errorMsg[0] + errorMsg[1] + errorMsg[2]);
                enableCommentButton();
                return false;
            } else {
                userCommentId = $(selector.commentList, data).html().match(/id=\&quot;?comment-\d+/g).join().match(/\d+/g).sort(function(a, b) {
                    return a - b;
                }).pop();
                commentLi = '&lt;li id=&quot;comment-' + userCommentId + '&quot; class=&quot;comment&quot;&gt;' + $('#comment-' + userCommentId, data).html(); + '&lt;\/li&gt;';
                if (parentId) {
                    if ($('#' + parentId).find(&quot;.comment-children&quot;).length &lt;= 0) {
                        $('#' + parentId).append(&quot;&lt;ul class='children'&gt;&lt;/ul&gt;&quot;);
                    }
                    $('#' + parentId + &quot; .children:first&quot;).append(commentLi);
                    parentId = ''
                    $body.animate({
                        scrollTop: $('#comment-' + userCommentId).offset().top - 450
                    }, 900);
                } else {
                    $(selector.commentList).prepend(commentLi)
                    $body.animate({
                        scrollTop: $('#comment-' + userCommentId).offset().top - 200
                    }, 900);
                }
                //$('#comment-' + userCommentId).slideDown('slow');

                //console.log(userCommentId);
                $(selector.commentNumText).length ? (n = parseInt($(selector.commentNumText).text().match(/\d+/)), $(selector.commentNumText).html($(selector.commentNumText).html().replace(n, n + 1))) : 0;
                TypechoComment.cancelReply();
                $(selector.submitTextarea).val('');
                $(selector.commentReplyButton + ' b, #cancel-comment-reply-link').unbind('click');
                bindCommentReplyButton();
                enableCommentButton();

            }
        }
    });
    return false;
});

function bindCommentReplyButton() {
    $(document).on('click', selector.commentReplyButton, function() {
        parentId = $(this).parents('li.comment').attr(&quot;id&quot;);
        $(selector.submitTextarea).focus();
    });
    $(document).on('click', '#cancel-comment-reply-link', function() {
        parentId = '';
    });
}

function enableCommentButton() {
    $(selector.submitButton).attr('disabled', false).fadeTo('', 1);
    $(selector.submitButton).val('发射=A=');
}

function message(msg) {
    $msg.hide();
    $msg.html(msg).slideToggle('fast');
}

}

无限嵌套评论

function themeInit($archive)
{

Helper::options()-&gt;commentsMaxNestingLevels = 999;

}

非插件实现路由

function themeInit($archive)
{

if ($archive-&gt;is('archive', 404))
{
    $path_info = trim($archive-&gt;request-&gt;getPathinfo(), '/');
    if ($path_info == 'i/redirect')
    {
        $url = urldecode($archive-&gt;request-&gt;url);
        $archive-&gt;response-&gt;redirect($url);
        exit;
    }
}

}

2017年11月20日