Handsome主题Github页面重构

简介

在handsom使用文档中及github.php​文件中,可以知道,作者使用了github的api来获取仓库信息,无法自定义输出项目清单。此外,关于本部分的开发作者也尚未完成,再加上个人对于该样式并不是很喜欢,因此希望重构该页面以支持自定义输出Github项目(并顺带也稍微了解一下php语言,纯外行,代码有改的不好的地方求轻喷)。具体效果可见左侧 Github页面

本页面使用Github anuraghazra/github-readme-stats 项目来生成repo及个人详情卡片

省流: 直接复制文末的代码替换原typecho/usr/themes/handsome/github.php​文件。(注意做好备份,以防不时之需)

1. 分析

首先打开该文件typecho/usr/themes/handsome/github.php​,分析一下该页面的代码。

元素模板

首先定义了元素模板,等后续使用Github api调取repo信息之后直接填充就好

var githubItemTemple = '<div class="col-xs-12 col-sm-6">'+
'<div class="panel b-light {BG_COLOR}">\n' +
'        <div class="panel-body"><div class="github_language">{PROJECT_LANGUAGE}</div>' +
'          \n' +
'          <div class="clear">\n' +
'            <span class="text-ellipsis font-thin h3">{REPO_NAME}</span>\n' +
'            <small class="block m-sm"><i class="iconfont icon-star m-r-xs"></i>{REPO_STARS} stars / <i class="iconfont icon-fork"></i> {REPO_FORKS} forks</small>\n' +
    '<small class="text-ellipsis block text-muted">{REPO_DESC}</small>'+
'<a target="_blank" href="{REPO_URL}" class="m-sm btn btn-rounded btn-sm lter btn-{BUTTON_COLOR}"><i class="glyphicon glyphicon-hand-up"></i>访问</a>' +
'          </div>\n' +
'        </div>\n' +
'      </div>'+
'</div>';

项目信息获取

使用jQuery.get()​方法通过github api接口https://api.github.com/users/<?php echo $githubUser; ?>/repos​来获取用户的仓库信息。

在该函数中,首先使用contentContainer​来获取所在元素区域,接着就append()​把模板元素填充后加进来就行了。

$.get("https://api.github.com/users/<?php echo $githubUser; ?>/repos",function(result){
    if(result){
        loadingContainer.addClass("hide");
        var ul = $("<div class='raw'><div class='col-md-12'><div class=\"row row-sm text-center " +
            "github_contain" +
            "\"></div></div></div>");
        repoContainer.append(ul);
        var contentContainer = $(".github_contain");
        for(var i in result){
            var repo = result[i];
            repo.updated_at = repo.updated_at.substring(0,repo.updated_at.lastIndexOf("T"));
            if (repo.language == null){
                repo.language = "未知";
            }
            //匹配替换
            var item = githubItemTemple.replace("{REPO_NAME}",repo.name)
                .replace("{REPO_URL}",repo.html_url)
                .replace("{REPO_STARS}",repo.stargazers_count)
                .replace("{REPO_FORKS}",repo.forks_count)
                .replace("{REPO_DESC}",repo.description)
                .replace("{BG_COLOR}","bg-"+colors[i % 8])
                .replace("{BUTTON_COLOR}",colors[(i) % 8])
                .replace("{PROJECT_LANGUAGE}",repo.language);
            contentContainer.append(item);
        }
    }else{
        errorContainer.removeClass("hide");
    }
});

分析完之后我们就可以针对模板进行修改就行了。

2. 定制化修改

个人信息卡片

<div id="post-content" class="wrapper-lg">​下面的第一个<div class="l-h-2x row">​下面进行修改。

<div class="wrapper-md">
    <!--博客文章样式 begin with .blog-post-->
    <div id="postpage" class="blog-post">
        <article class="single-post panel">
            <!--文章页面的头图-->
            <?php echo Content::exportHeaderImg($this); ?>
            <!--文章内容-->
            <div id="post-content" class="wrapper-lg">
                <div class="l-h-2x row">
                <?php
                    $githubUser = $this->fields->github;

                    if ($githubUser == "" || $githubUser == null){
                    echo
                    '<script>$(".github_tips").text("请填写正确的github用户名,主题检查github用户为空或者错误,已经切换zideliu用户仓库项目。");</script>';
                    $githubUser = 'zideliu';
                    }
                    $githubRepos = $this->fields->githubRepos;

                    // $githubRepos = explode(",",$githubRepos);
                    if ($githubRepos == "" || $githubRepos == null){
                    // echo
                    '<script>$(".github_tips").text("请填写正确的github仓库名,主题检查github仓库名为空或者错误,已经切换zideliu用户仓库项目。");</script>';
                    $githubRepos = "zideliu/StyleDrop-Pytorch, zideliu/Text-To-Video-Finetuning";
                    }
                ?>
                <div class="col-xs-12 col-sm-12">
                <center>
                    <div class="col-xs-12 col-sm-6">
                        <a href="https://github.com/zideliu">
                            <img align="center"
                                src="https://github-readme-stats-one-bice.vercel.app/api?username=<?php echo $githubUser; ?>&show_icons=true&theme=transparent&hide_border=true&count_private=true&include_orgs=true&role=OWNER,COLLABORATOR"
                                alt="Zideliu's github stats"  />
                        </a>
                    </div>
                    <div class="col-xs-12 col-sm-6">
                        <a href="https://github.com/zideliu">
                            <img align="center" src="https://github-readme-stats-one-bice.vercel.app/api/top-langs/?username=<?php echo $githubUser; ?>&theme=transparent&hide_border=true&count_private=true&layout=compact&hide=java,CSS&include_orgs=true&role=OWNER,COLLABORATOR" />
                        </a>
                    </div>
                </center>
                </div>
                <div class="svg-container" style="display: flex;justify-content: center;width: 100%;">
                <svg height="20" width="75%" viewBox="0 0 300 20">
                    <!-- 左半部分的线 -->
                    <line x1="-150" y1="10" x2="120" y2="10" stroke="#8957e5" stroke-width="2"stroke-dasharray="5,5" stroke-opacity="0.5"/>
                
                    <!-- 菱形 -->
                    <path d="M150 4 L156 10 L150 16 L144 10 Z" fill="none" stroke="#8957e5" stroke-width="2"/>
                
                    <!-- 右半部分的线 -->
                    <line x1="180" y1="10" x2="450" y2="10" stroke="#8957e5" stroke-width="2"stroke-dasharray="5,5" stroke-opacity="0.5"/>
                </svg>
                </div>

在该代码的第10行~第54行为我们添加的内容,首先,先判断当前github​用户及githubRepos​有没有输入,没有的话做赋予默认值。githubRepos值的格式为<github用户名>/<仓库名>,如zideliu/StyleDrop-Pytorch​。

<?php
    $githubUser = $this->fields->github;

    if ($githubUser == "" || $githubUser == null){
    echo
    '<script>$(".github_tips").text("请填写正确的github用户名,主题检查github用户为空或者错误,已经切换zideliu用户仓库项目。");</script>';
    $githubUser = 'zideliu';
    }
    $githubRepos = $this->fields->githubRepos;

    // $githubRepos = explode(",",$githubRepos);
    if ($githubRepos == "" || $githubRepos == null){
    // echo
    '<script>$(".github_tips").text("请填写正确的github仓库名,主题检查github仓库名为空或者错误,已经切换zideliu用户仓库项目。");</script>';
    $githubRepos = "zideliu/StyleDrop-Pytorch, zideliu/Text-To-Video-Finetuning";
    }
?>

然后添加个人信息卡片,使用github-readme-stats,具体用法看Repo的README文件,这里不再赘述。

<div class="col-xs-12 col-sm-12">
<center>
    <div class="col-xs-12 col-sm-6">
        <a href="https://github.com/<?php echo $githubUser; ?>">
            <img align="center"
                src="https://github-readme-stats-one-bice.vercel.app/api?username=<?php echo $githubUser; ?>&show_icons=true&theme=transparent&hide_border=true&count_private=true&include_orgs=true&role=OWNER,COLLABORATOR"
                alt="Zideliu's github stats"  />
        </a>
    </div>
    <div class="col-xs-12 col-sm-6">
        <a href="https://github.com/<?php echo $githubUser; ?>">
            <img align="center" src="https://github-readme-stats-one-bice.vercel.app/api/top-langs/?username=<?php echo $githubUser; ?>&theme=transparent&hide_border=true&count_private=true&layout=compact&hide=java,CSS&include_orgs=true&role=OWNER,COLLABORATOR" />
        </a>
    </div>
</center>
</div>

完成上述操作之后,预期效果如下:

为了能够稍微提升一下美观度,这里使用Claude(真是太强了,惊艳到我了),让其帮忙生成了一条线作为分隔。

<div class="svg-container" style="display: flex;justify-content: center;width: 100%;">
<svg height="20" width="75%" viewBox="0 0 300 20">
    <!-- 左半部分的线 -->
    <line x1="-150" y1="10" x2="120" y2="10" stroke="#8957e5" stroke-width="2"stroke-dasharray="5,5" stroke-opacity="0.5"/>
  
    <!-- 菱形 -->
    <path d="M150 4 L156 10 L150 16 L144 10 Z" fill="none" stroke="#8957e5" stroke-width="2"/>
  
    <!-- 右半部分的线 -->
    <line x1="180" y1="10" x2="450" y2="10" stroke="#8957e5" stroke-width="2"stroke-dasharray="5,5" stroke-opacity="0.5"/>
</svg>
</div>

Github项目卡片

接下来便是展示项目卡片

代码展开

<script type="text/javascript">
var temp = <?php echo json_encode($githubRepos); ?>;
console.log(temp);
var githubItemTemple = '<div class="col-xs-12 col-sm-6" style="padding-left: 0px; padding-right: 0px;">\n' +
    '<a href="https://github.com/{USER}/{REPO_NAME}">\n' +
    '<img align="center" src="https://github-readme-stats.vercel.app/api/pin/?username={USER}&repo={REPO_NAME}&theme=transparent" />\n' +
    '</a>'
'</div>';
var test = githubItemTemple.replace(/{REPO_NAME}/g, temp);

var open = function() {
    var handleGithub = function() {
        var repoContainer = $('.github_page');
        var loadingContainer = repoContainer.find(".loading-nav");
        var errorContainer = repoContainer.find(".error-nav");
        var countContainer = $(".github_tips");
        var githubrepos = <?php echo json_encode($githubRepos); ?>;
        githubrepos = githubrepos.split(", ");

        var ul = $("<div class='raw'><div class='col-md-12'><div class=\"row row-sm text-center " +
            "github_contain" +
            "\"></div></div></div>");
        repoContainer.append(ul);
        var contentContainer = $(".github_contain");
        for (let repo_item of githubrepos) {
            var repo_name = repo_item.split("/")[1];
            var repo_user = repo_item.split("/")[0];
            var item = githubItemTemple.replace(/{REPO_NAME}/g, repo_name).replace(/{USER}/g,repo_user);
            loadingContainer.addClass("hide");
            contentContainer.append(item);
        };

    }
    return {
        init: function() {
            handleGithub();
        }
    };
}
$(open().init);
</script>

这里需要注意的地方有三个:

  1. 这里我是参考原模板的写法,对其进行适配
  2. 不需要jQuery去获取api信息,而是通过用户输入
  3. 注意loadingContainer.addClass("hide");​该函数,如果仅有var loadingContainer = repoContainer.find(".loading-nav");​则会一直出现loading​的字样

对于输入的格式要求,在本文中,规定要求为<用户名>/<仓库名>,由该代码的第26、27行可见(repo_user​ 和 repo_name​ 分别为repo_item.split("/")​的第一项和第二项目)

汇总

最后将其汇总到一个文件内就行,修改后的github.php​文件如下

代码展开

<?php
/**
* github项目列表
*
* @package custom
*/
if (!defined('__TYPECHO_ROOT_DIR__')) exit;

?>

<?php $this->need('component/header.php'); ?>

<!-- aside -->
<?php $this->need('component/aside.php'); ?>
<!-- / aside -->

<!-- <div id="content" class="app-content"> -->
<a class="off-screen-toggle hide"></a>
<main class="app-content-body <?php Content::returnPageAnimateClass($this); ?>">
    <div class="hbox hbox-auto-xs hbox-auto-sm">
        <!--文章-->
        <div class="col center-part gpu-speed" id="post-panel">
            <div class="bg-light lter wrapper-md">
                <h1 class="entry-title m-n font-thin text-black l-h"><span
                        class="title-icons"><i
                            data-feather="github"></i></span><?php _me("项目展示")
                    ?></h1>
                <?php if (trim($this->fields->intro) !== ""): ?>
                <div
                    class="entry-meta text-muted  m-b-none small post-head-icon"><?php
                    echo $this->fields->intro; ?>
                </div>
                <?php endif ?>
            </div>
            <div class="wrapper-md">
                <!--博客文章样式 begin with .blog-post-->
                <div id="postpage" class="blog-post">
                    <article class="single-post panel">
                        <!--文章页面的头图-->
                        <?php echo Content::exportHeaderImg($this); ?>
                        <!--文章内容-->
                        <div id="post-content" class="wrapper-lg">
                            <div class="l-h-2x row">
                            <?php
                                $githubUser = $this->fields->github;

                                if ($githubUser == "" || $githubUser == null){
                                echo
                                '<script>$(".github_tips").text("请填写正确的github用户名,主题检查github用户为空或者错误,已经切换zideliu用户仓库项目。");</script>';
                                $githubUser = 'zideliu';
                                }
                                $githubRepos = $this->fields->githubRepos;

                                // $githubRepos = explode(",",$githubRepos);
                                if ($githubRepos == "" || $githubRepos == null){
                                // echo
                                '<script>$(".github_tips").text("请填写正确的github仓库名,主题检查github仓库名为空或者错误,已经切换zideliu用户仓库项目。");</script>';
                                $githubRepos = "zideliu/StyleDrop-Pytorch, zideliu/Text-To-Video-Finetuning";
                                }
                            ?>
                                <div class="col-xs-12 col-sm-12">
                                <center>
                                    <div class="col-xs-12 col-sm-6">
                                        <a href="https://github.com/<?php echo $githubUser; ?>">
                                            <img align="center"
                                                src="https://github-readme-stats-one-bice.vercel.app/api?username=<?php echo $githubUser; ?>&show_icons=true&theme=transparent&hide_border=true&count_private=true&include_orgs=true&role=OWNER,COLLABORATOR"
                                                alt="Zideliu's github stats"  />
                                        </a>
                                    </div>
                                    <div class="col-xs-12 col-sm-6">
                                        <a href="https://github.com/<?php echo $githubUser; ?>">
                                            <img align="center" src="https://github-readme-stats-one-bice.vercel.app/api/top-langs/?username=<?php echo $githubUser; ?>&theme=transparent&hide_border=true&count_private=true&layout=compact&hide=java,CSS&include_orgs=true&role=OWNER,COLLABORATOR" />
                                        </a>
                                    </div>
                                </center>
                                </div>
                                <div class="svg-container" style="display: flex;justify-content: center;width: 100%;">
                                <svg height="20" width="75%" viewBox="0 0 300 20">
                                    <!-- 左半部分的线 -->
                                    <line x1="-150" y1="10" x2="120" y2="10" stroke="#8957e5" stroke-width="2"stroke-dasharray="5,5" stroke-opacity="0.5"/>
                                
                                    <!-- 菱形 -->
                                    <path d="M150 4 L156 10 L150 16 L144 10 Z" fill="none" stroke="#8957e5" stroke-width="2"/>
                                
                                    <!-- 右半部分的线 -->
                                    <line x1="180" y1="10" x2="450" y2="10" stroke="#8957e5" stroke-width="2"stroke-dasharray="5,5" stroke-opacity="0.5"/>
                                </svg>
                                </div>
                                <?php
                                Content::postContentHtml($this,$this->user->hasLogin());
                                ?>
                            
                                <small
                                    class="text-muted letterspacing github_tips"></small>
                                <!--github--->
                                <div class="github_page">
                                    <nav
                                        class="loading-nav text-center m-t-lg m-b-lg">
                                        <p class="infinite-scroll-request"><i
                                                class="animate-spin fontello
                      fontello-refresh"></i><?php _me("Loading……") ?></p>
                                    </nav>
                                    <nav
                                        class="error-nav hide text-center m-t-lg m-b-lg">
                                        <p class="infinite-scroll-request"><i
                                                class="glyphicon
                            glyphicon-refresh"></i>加载失败!尝试重新加载</p>
                                    </nav>
                                </div>
                            </div>
                        </div>
                    </article>
                </div>
                <!--评论-->
                <?php $this->need('component/comments.php') ?>
            </div>
            <?php echo WidgetContent::returnRightTriggerHtml() ?>
        </div>
        <!--文章右侧边栏开始-->
        <?php $this->need('component/sidebar.php'); ?>
        <!--文章右侧边栏结束-->
    </div>
    <script type="text/javascript">
    var temp = <?php echo json_encode($githubRepos); ?>;
    console.log(temp);
    var githubItemTemple = '<div class="col-xs-12 col-sm-6" style="padding-left: 0px; padding-right: 0px;">\n' +
        '<a href="https://github.com/{USER}/{REPO_NAME}">\n' +
        '<img align="center" src="https://github-readme-stats.vercel.app/api/pin/?username={USER}&repo={REPO_NAME}&theme=transparent" />\n' +
        '</a>'
    '</div>';
    var test = githubItemTemple.replace(/{REPO_NAME}/g, temp);

    var open = function() {
        var handleGithub = function() {
            var repoContainer = $('.github_page');
            var loadingContainer = repoContainer.find(".loading-nav");
            var errorContainer = repoContainer.find(".error-nav");
            var countContainer = $(".github_tips");
            var githubrepos = <?php echo json_encode($githubRepos); ?>;
            githubrepos = githubrepos.split(", ");
            var ul = $("<div class='raw'><div class='col-md-12'><div class=\"row row-sm text-center " +
                "github_contain" +
                "\"></div></div></div>");
            repoContainer.append(ul);
            // contentContainer.append('<div class="custom-hr" style="height: 2px;background-color: #e1e4e8;margin: 20px 0;}"></div>')
            var contentContainer = $(".github_contain");
            for (let repo_item of githubrepos) {
                var repo_name = repo_item.split("/")[1];

                var repo_user = repo_item.split("/")[0];

                var item = githubItemTemple.replace(/{REPO_NAME}/g, repo_name).replace(/{USER}/g,repo_user);
                loadingContainer.addClass("hide");

                contentContainer.append(item);
            };

        }
        return {
            init: function() {
                handleGithub();
            }
        };
    }
    $(open().init);
    </script>
</main>

<!-- footer -->
<?php $this->need('component/footer.php'); ?>
<!-- / footer -->

总体的页面效果为

最后修改:2024 年 09 月 14 日
如果觉得我的文章对你有用,请随意赞赏