$30 off During Our Annual Pro Sale. View Details »

GitHubをCMSとして使う話/ using_github_as_CMS

GitHubをCMSとして使う話/ using_github_as_CMS

Masahiko Sakakibara

June 14, 2023
Tweet

More Decks by Masahiko Sakakibara

Other Decks in Programming

Transcript

  1. ୤ɾແݶΧελϜϑΟʔϧυ
    ʙಈత$.4Λ΍Ίͯɺ(JU)VCΛ$.4ͱͯ͠࢖͏࿩

    View Slide

  2. ࣗݾ঺հ
    ࡗݪণ඙
    Ұൠࣾஂ๏ਓϦϨʔγϣϯσβΠϯ

    ݚڀॴ୅දཧࣄ
    Ұൠࣾஂ๏ਓΤϦΞɾ

    ΠϊϕʔγϣϯɾΞϥΠΞϯε$50
    *POJD+BQBO6TFS(SPVQ

    ୅ද
    *POJD%FWFMPQFS&YQFSU 4USJQF$PNNVOJUZ&YQFSU

    View Slide


  3. UJQTZT

    View Slide

  4. ৯඼දࣔҹ࡮
    εϚϗͱϓϦϯλ͚ͩͰ৯඼දࣔϥ
    ϕϧΛͭ͘ΕΔ೔ຊॳͷઐ༻ΞϓϦ

    View Slide

  5. XJOFDPEF
    ଟछྨଟ਺ྔͷϫΠϯΛෳ਺ڌ఺Ͱ؅ཧͰ
    ͖Δ೔ຊ།ҰͷΞϓϦɻ

    View Slide

  6. $.4ߏங͸᠘͕͍ͬͺ͍

    View Slide

  7. ιϑτ΢ΣΞͷϝϯςφϯε
    IUUQTFOEP
    fl
    JGFEBUF

    View Slide

  8. ϓϥάΠϯͷ࠾༻੹೚

    View Slide

  9. ߏ଄͕೉͍͠΋ͷΛߋ৽Մೳʹʁ

    View Slide

  10. όοΫΞοϓͷϝϯςφϯε
    %#ਧ͖ඈͼ·ͨ͠ɻ

    ࠷ऴόοΫΞοϓͬͯࡢ೔Ͱ͢ΑͶʁʂ
    ઌ݄͔ΒόοΫΞοϓͱΕͯ·ͤΜͰͨ͠ɻ

    σΟεΫ༰ྔ͕͍ͬͺ͍ͩͬͨΑ͏Ͱ͢ɻ
    Ͳ͏ͨ͠Β͍͍ΜͰ͔͢ʁʂʁʂ
    Ͳ͏ʹ΋ͳΓ·ͤΜɾɾɾɻ

    View Slide

  11. ΞΫηεूதͨ࣌͠ͷରԠ
    8FCαΠτ͕ݟΕͳ͍Μ͚ͩͲͲ͏ͯ͠ʁ

    ͔ͤͬ͘ςϨϏʹऔΓ্͛ΒΕͨͷʹɻ
    ΞΫηε͕ूதͯ͠αʔό͕མ͔ͪͨΒͰ͢Ͷɻ

    མͪண͘·Ͱ଴͔ͭ͠Ͱ͖ͳ͍Ͱ͢ɻ
    Ͳ͏ͨ͠Β͍͍ΜͰ͔͢ʁʂʁʂ
    ͕ͬͭΓαʔόʹ͓͍ۚΕͯ࠶ൃ๷ࢭΛʂ

    View Slide

  12. Ϣʔβ͕ϨΠΞ΢τΛյ͢
    Ͳ͜Λߋ৽ͨ͠Β͍͍ʁ
    "ͱ#ͷϑΟʔϧυΛߋ৽͍ͯͩ͘͠͞ɻ
    $ͷϑΟʔϧυΛߋ৽ͨ͠Β͜ΘΕͨʂ
    $ͷϑΟʔϧυΛߋ৽͔ͨ͠ΒͰ͢ɻ

    View Slide

  13. ϗεςΟϯάྉۚ
    ֹ݄ Φʔτεέʔϧ 1)1.Z42-
    /FUMJGZ 0ԁʙ ͋Γ ෆՄ
    'JSFCBTF
    )PTUJOH
    0ԁʙ ͋Γ ෆՄ
    4ࣾ 425ԁʙ ͳ͠ Մ
    "ࣾ 20999.70ԁʙ ͳ͠ Մ

    View Slide

  14. Ϣʔβ͕ߋ৽͢ΔࣗࣾαΠτͰ͸ɺ$.4ߏஙɻ
    ͦΕɺඞཁͰ͔͢ʁ

    View Slide

  15. ੔ཧͯ͠ߟ͑Α͏
    ͳͥ$.4ߏங͕ඞཁʁ
    ̍ɽ)5.-Λॻ͚ͳ͍Ϣʔβ͕ߋ৽Ͱ͖ΔΑ͏ʹ͢ΔͨΊ
    ̎ɽಉҰςϯϓϨʔτͰྔ࢈ͨ͠هࣄΛ؅ཧ͢ΔͨΊ

    ɹɹʢྫɿχϡʔεαΠτʣ
    ̏ɽ&$αΠτߏஙͳͲෳࡶͳखॱ͕ඞཁͳ΋ͷΛखܰʹߏங͢ΔͨΊ

    View Slide

  16. ͜Ε(JU)VCͰղܾͰ͖Δʂ

    View Slide

  17. ̍ɽ)5.-Λॻ͚ͳ͍Ϣʔβ͕ߋ৽Ͱ͖ΔΑ͏ʹ͢ΔͨΊ
    ؆୯ͳϖϥΠνͩͬͨΒɺ͜ͷϨϕϧͰ͍͚Δɻ

    View Slide

  18. ϑϨϯνͷΦʔφʔγΣϑ
    ʮ͜ΕݟͨΒߋ৽Ͱ͖ͨΑʯ

    View Slide

  19. ·ͪͮ͘Γձࣾͷελοϑ
    ʮΩʔࣗମΛؒҧͬͯ࡟আͨ͠Βɺࣦഊͨͬͯ͠ϝʔϧ͖ͨʯ

    View Slide

  20. ·ͪͮ͘Γձࣾͷελοϑ
    ॻ͖׵͙͑Β͍Ͱ͖ΔΑɻ

    View Slide

  21. ࣮૷ྫ̍ɿࣗ࡞ςϯϓϨʔτ

    export interface IItem {
    selector: string;
    template: string;
    data: Array<{ title?: string; ja?: string; price?: string; body?: string;
    image?: string }>;
    }
    export const news: IItem = {
    selector: '',
    template: '{{ title }}{{ body }}
    p>',
    data: [
    {
    title: 'ίϩφײછ঱༧๷ରࡦ',
    body: 'ίϩφײછ঱༧๷ରࡦͱͯ͠ɺۭؾͷೖΕସ͑ɺִؒʹ༨༟ͷ͋Δ੮΁ͷ͝Ҋ಺ɺΞΫϦ
    ϧ൘౳ɺ઀٬ελοϑͷϚεΫண༻ͳͲͷରԠΛ͓ͯ͠٬༷Λ͓ܴ͍͑ͨ͠·͢ɻ
    ౰ళ͸ɺ৽ܕίϩ
    φ΢ΠϧεରࡦೝূళͰ͢ɻ
    2࣌ؒఔ౓Ͱͷ͓৯ࣄΛ͓ئ͍͍ͨ͠·͢ɻ',
    },
    ],
    };

    )5.-
    5ZQF4DSJQU

    View Slide

  22. ࣮૷ྫ̍ɿ͜Μͳ/PEFΛ࣮ߦͯ͠#VJME
    const targets = ['index.html'];
    const items: IItem[] = [news, redWine, whiteWine, champagneWine, announcement];
    const build = () => {
    execSync(`rm -r -f ${process.cwd() + '/www'}`);
    mkdirSync(process.cwd() + '/www');
    execSync(`cp -r ${process.cwd() + '/src/template'}/* ${process.cwd() + '/www'}`);
    for (const templateFile of targets) {
    let template = readFileSync(process.cwd() + '/www/' + templateFile).toString('utf-8');
    for (const item of items) {
    const insertData: string[] = [];
    for (const line of item.data) {
    let template = item.template;
    for (const [key, value] of Object.entries(line)) {


    const re_url = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/
    gi;
    const replaceText = (value as string).replace(re_url, 'rel="noreferrer">$1');
    template = template.replace(new RegExp(`{{ ${key} }}`, 'g'), replaceText as string);
    }
    insertData.push(template);
    }
    const changeSelector = item.selector.replace(/>${insertData.join('')}<`);
    template = template.replace(item.selector, changeSelector);
    }
    writeFileSync(process.cwd() + '/www/' + templateFile, template);
    }
    };
    build();
    createWineSearchIndex();
    apiBuild();
    5ZQF4DSJQU

    View Slide

  23. ࣮૷ྫ̎ɿ+BWB4DSJQUϑϨʔϜϫʔΫ


    ͓஌Βͤ




    {news.map(d => innerHTML={d.body}>
    )}

    +49
    ͜Ε͚ͩͰॻ͚ͪΌ͏ɻ؆୯ʂ

    View Slide

  24. ಉҰςϯϓϨʔτͰྔ࢈ͨ͠هࣄΛ؅ཧ͢ΔͨΊ
    ϔουϨε$.4Λ࢖ͬͯಈతʹσʔλऔಘ͠Α͏
    8PSE1SFTTDPN
    NJDSP$.4
    LJOUPOF

    View Slide

  25. ಉҰςϯϓϨʔτͰྔ࢈ͨ͠هࣄΛ؅ཧ͢ΔͨΊ
    {
    path: ':id',
    component: ArticlePage,
    },
    this.route.paramMap.subscribe(as
    ync (params: ParamMap) => {
    this.articleId =
    parseInt(params.get('id'), 10);
    const {article} = await
    this.articleService.getCategory(
    this.articleId
    );
    this.article = article;
    });


    h3>

    {{ item.date | date:
    "yyyy೥MM݄dd೔" }}
    *ngIf="item.count"> /
    {{ item.count }}Point

    class="excerpt" [innerHTML]="item.
    excerpt">

    View Slide

  26. 44(443QSFSFOEFSJPΛ࢖ͬͯϨϯμϦϯά΋Ͱ͖Δ
    ಺༰
    $43 Ϣʔβ؀ڥͰHTMLΛϨϯμϦϯά
    44( αʔόϗεςΟϯάલʹHTMLΛϨϯμϦϯά
    443 ϦΫΤετ࣌ʹHTMLΛϨϯμϦϯά
    QSFSFOEFSJP
    ಛఆIP͔ΒͷϦΫΤετ͚࣌ͩɺαʔό͕ϨϯμϦ
    ϯάࡁΈHTMLΛฦ٫

    View Slide

  27. ٕज़ͷ՝୊͸ٕज़Ͱղܾ͠Α͏
    ಈతݴޠ͕૸Δαʔόͷ੹೚όοΫΞοϓ΍αʔόෛՙͷίϯτ
    ϩʔϧϢʔβ͕յͨ͠ΒͲ͏͠Α͏FUD
    ΋ͪΖΜϦεΫϚωʔδϝϯτ͠ͳ͕Β$.4ߏங΋͋ΓͰ͕͢ɺ
    ੩తαΠτԽ͢Δ͜ͱͰ͜ΕΒͷ໰୊Λ৐Γӽ͑ΕΔՄೳੑ͕͋Δ
    ͷͰҰ౓ߟ͑ͯΈ·ͤΜ͔ɻ

    View Slide