Guide to the Project Layout File - hackforla/website GitHub Wiki

## Contents

  1. Visible
  2. Layout
  3. Hero Image
  4. Project Status
  5. Project Links
  6. Tools and Technologies
  7. Open Roles
  8. Getting Started Button
  9. Getting Started Panel
  10. Project Leadership
  11. Project Contributors
  12. Resource Card

JavaScript Code

  1. Fetching Correct Project
  2. Adding Languages
  3. Constructing Team Card
  4. Getting Started Drop Down
  5. Call to Action Message

content markdownify - page.hero-image looping thru that for leadership - variables defined in markdown for text underneath front matter, and content of blog post - markdownify would take all text outside of front matter and dump it into page -take it out and test it to see if it braks or not, if everythingis ok - delete/remove it


Visible

To include a page on the site's project listing, your card should contain the following line. If you do not want the project to be listed, change visible to "false".

---
visible: true
---

Layout

The project layout incorporates the default layout, which contains the head, header, and footer elements.

---
layout: default
---

Hero Image

If a hero-image for the project is available - the project markdown file will, for example, include:

image which will be displayed on top of the project page. If the image is not available, an image of a color block will serve as its placeholder. When compiled, the color block will be shown as a gradient because a gradient effect has been styled into the project layout via _project-page.scss.

image

A note about image naming conventions:
In the assets\images\projects folder, you'll see the images for all the projects. Images for the project cards are named after the project itself, images to be displayed on the project page will have a -hero appended to the project name. Use - instead of spaces for projects with longer names: for example, food-oasis.

image

{% if page.image-hero %}
    <header style='background: url({{ page.image-hero }}) center center no-repeat;' class='project-hero'>
{% else %}
    <header style='background: url(/assets/images/hero/hacknight-women.jpg) center center no-repeat;' class='project-hero'>
{% endif %}
        <h1 class='hero-inner'>{{ page.title }}</h1>
    </header>

<div class='content-section project-home-page'>
    <!--Project Description Card-->
    <div id='project-description-card' class='project-page-card' style='padding-bottom: 19px;'>
        <h4 style='color:#333'>Project Overview</h4>
        <!--Project Details-->
        <div class='project-page-description'>

Project Status

Depending on the project status, the filter will change the status background-color according to the CSS in _sass\components_projects.scss using the classes status-indicator and status-text (with 'text' being replaced with the status from the front matter declared in the markdown file).

image image

            <!--Project Properties-->
            <div class='description-grid-item'>
                {% if page.status %}
                    <div>
                        <p style='display:inline-block'><strong>Status: </strong></p>
                        <div style='display:inline-block; float:none' class='status-indicator {{ "status-" | append: page.status }}'>
                            <h5 class='status-text'>{{ page.status }}</h5>
                        </div>
                    </div>
                {% endif %}
                {% if page.partner %}<p><strong>Partner: </strong>{{ page.partner }}</p>{% endif %}
                {% if page.location %}<p><strong>Location: </strong>{{ page.location }}</p>{% endif %}


Project Links

The following code is for placing project links. First, we'll count the number of links listed in the markdown file. For lists over the length of 1, we'll add commas to the list, using the counter to keep our count and as to avoid adding a comma after the last link. This list is prioritizing Github and Site links for the Project Overview section of the project page. All other links are placed into the Resource section at the bottom of the project page.

image

image

                <!-- Links Logic to filter prioritized links and to correct comma placement -->
                {% if page.links %}
                    {% assign counter = 0 %}
                    {% for item in page.links %}
                        {% if item.name == 'GitHub' or item.name == 'Test Site' or item.name == 'Demo Site' or item.name == 'Site' %}
                            {% assign counter = counter | plus:1 %}
                        {% endif %}
                    {% endfor %}
                    {% if counter > 0 %}
                        <p>
                            <strong>Links: </strong>
                            {% for item in page.links %}
                                {% if item.name == 'GitHub' or item.name == 'Test Site' or item.name == 'Demo Site' or item.name == 'Site' %}
                                    {% if counter > 1 %}
                                        <a target="_blank" href='{{ item.url }}'> {{ item.name }}</a>,
                                        {% assign counter = counter | minus:1 %}
                                    {% elsif counter <= 1 %}
                                        <a target="_blank" href='{{ item.url }}'> {{ item.name }}</a>
                                    {% endif %}
                                {% endif %}
                            {% endfor %}
                        </p>
                    {% endif %}
                {% endif %}

Tools and Technologies

The following code compiles the lists of the tools and technologies used in the project. As tools are in a string-list format in the front matter, there is no need for a loop.
image

The technologies have to be looped through as they in the markdown list format, and an if condition is needed because not all projects have listed their technologies used.
image

Lastly, languages are pulled from Github instead of the project markdown file. Therefore, a script for Adding Languages is used instead.

                {% if page.tools %}<p><strong>Tools: </strong>{{ page.tools }}</p>{% endif %}
                <p id='languages'><strong>Languages: </strong></p>
                {% if page.technologies %}
                <p id='technologies'><strong>Technologies: </strong>
                  {% for tech in page.technologies %}
                    {{ tech }}{% if forloop.last == false %},{% endif %}
                  {% endfor %}
                </p>
                {% endif %}            
             </div>

Open Roles

Description and open roles for the project, with open roles structured as list items. This list is pulling from the looking: front matter of the project markdown file.

            <!--Project Summary and Getting Started Button-->
            <div class='description-grid-item'>
                <p>{{page.description}}</p>
                {% if page.status == "Completed" and page.completed-contact %}
                    <p>If you would like to talk to us about this completed project, please reach out to <a href="mailto:{{ page.completed-contact }}?subject=Question%20about%20{{ page.title }}">{{ page.completed-contact }}</a></p>
                {% elsif page.status == "Completed" %}
                    <p>If you would like to talk to us about this completed project, please reach out to <a href="mailto:[email protected]?subject=Question%20about%20{{ page.title }}">[email protected]</a></p>
                {% elsif page.looking %}
                <p class='open-roles'><strong>Open roles:</strong></p>
                <ul id='open-roles-list'>
                    {% for item in page.looking %}
                        <li><p class='role-paragraph'>{% if item.skill %}{{ item.skill }}{% endif %}</p></li>
                    {% endfor %}
                </ul>
                {% endif %}
            </div>
        </div>

Getting Started Button

Getting started accordion panel button.
image

        <div class="getting-started">
            <p style='margin-bottom:0px; white-space: nowrap;'>Getting Started</p>
            <button onClick='gettingStarted()' class='getting-started-button'>
                {% include svg/_ionicons_svg_ios-arrow-down.svg %}
            </button>
        </div>
    </div>

Getting Started Panel

When the getting started button is clicked, the panel will open to show this section. This section is using the resource-card.html from the _includes folder to create the layout. If the project has a Wiki and/or Readme, those files will appear on the page with an icon and link. If neither of those are defined in links in the project markdown file, the page will display a message: "Looks like this project doesn't have their own Getting Started guide."

image

    <!--Getting Started Card-->
    <div id="getting-started-section" class='project-page-card'>
        <ul class="resource-list unstyled-list">
            <!-- Hfla Start Guide -->
            {%- include resource-card.html name='Getting Started' url='https://github.com/hackforla/getting-started' -%}

            {% assign hasGettingStarted = false %}

            <!-- Check for Project Wiki -->
            {% for item in page.links %}
                {% if item.name == 'Wiki' %}
                    {% assign hasGettingStarted = true %}
                    {%- include resource-card.html name=item.name url=item.url image=page.image -%}
                {% endif %}
            {% endfor %}

            <!-- Check for Project Readme -->
            {% for item in page.links %}
                {% if item.name == 'Readme' %}
                    {% assign hasGettingStarted = true %}
                        {%- include resource-card.html name=item.name url=item.url image=page.image -%}
                {% endif %}
            {% endfor %}
            {% if hasGettingStarted == false %}
                <div id='help-getting-started'>
                    <p style='margin: 0px 15px 13px 15px;'>Looks like this project doesn't have their own Getting Started guide.</p>
                    <button onClick='helpMakeGuide()' class="btn btn-primary help-make-button" style='margin: 0 0 0 0;'>Help Make One!</button onClick=''>
                </div>
            {% endif %}
        </ul>
    </div>

Project Leadership

Project leadership is also defined in the project markdown file, the code below loops through the leadership list and outputs the cards, in the case the leadership is not listed, a message will be outputted instead.
Most project leaders will have links for their Github and Slack direct message, but in some cases, only their LinkedIn is provided. The code below checks for LinkedIn profiles for completed projects first, before it checks for the users' Github links. The rule for leadership cards is to link an individual's name to their Slack or LinkedIn, and for their photo/Github avatar to link to their Github or nothing (if clicked, a new tab will open to the project page).

    <!-- Project Team Card -->
    <div id='project-team-card' class='project-page-card'>
        <h4 style='color:#333'>Project Leadership</h4>
        {% if page.leadership %}
            <div class='resource-list'>
                {% for item in page.leadership %}
                    <div class='leader-card'>
                        <a href='{{ item.links.github }}' target='_blank' title='GitHub Profile'><img class='leader-img' src='{{ item.picture }}'/></a>
                        <div class='leader-description'>
                            {% if page.status == "Completed" and item.links.linkedin %}
                                <p style='margin-block-end: 0.25em;'><strong>Name: </strong><a href='{{ item.links.linkedin }}' target='_blank' title='Linkedin Profile'>{{ item.name }}</a></p>
                            {% elsif page.status == "Completed" %}
                               <p style='margin-block-end: 0.25em;'><strong>Name: </strong><a href='{{ item.links.github }}' target='_blank' title='GitHub Profile'>{{ item.name }}</a></p>
                            {% else %}
                                <p style='margin-block-end: 0.25em;'><strong>Name: </strong><a href='{{ item.links.slack }}' target='_blank' title='Slack Direct Message'>{{ item.name }}</a></p>
                            {%  endif %}
                            <p style='margin-block-end: 0.25em;'><strong>Role: </strong>{{ item.role }}</p>
                        </div>
                    </div>
                {% endfor %}
            </div>
        {% else %}
            <div class='empty-content-message'>
                <p>Looks like this project has not revealed specific leadership roles yet!</p>
            </div>
        {% endif %}


Project Contributors

The Contributors section with volunteers' Github avatar/profile picture and links are populated through DOM manipulation with JavaScript in the Constructing Team Card below. The script is using data being pulled through our github-actions with the data being stored in _data/github-data.json with objects of each project and their identification number, name, languages, url, and contributor list. The contributors' data includes their Github id number, github url, avator url, and a count of their contributions.

        <h4 id='contributor-header'style='color:#333'>Contributors</h4>
        <div id='contributors-list' class='resource-list'></div>
    </div>

Resource Card

The code below populates the Resource card, using resource-card.html from the _includes to create icons and links to the project's links (i.e. Github, Wiki, Slack, Project website, etc.).

image

    <!--Project Resources Card-->
    <div class='project-page-card'>
        <h4 style='color:#333'>Resources</h4>
        <ul class="resource-list unstyled-list">
            {%- for item in page.links -%}
                {% if item.name == 'Readme' or item.name == 'Wiki' %}
                    {%- include resource-card.html name=item.name url=item.url image=page.image -%}
                {% else %}
                    {%- include resource-card.html name=item.name url=item.url -%}
                {% endif %}
            {%- endfor -%}
        </ul>
    </div>
</div>
{{ content | markdownify }}

Return to Contents




JavaScript Code

Fetching Correct Project

The script is using data being pulled through our github-actions with the data being stored in _data/github-data.json with objects of each project and their identification number, name, languages, url, and contributor list. The contributors' data includes their Github id number, github url, avator url, and a count of their contributions. This script fetches the identification number and compares it against to markdown file to make sure it's correct. Within github\workflows\main.yml, you'll see that the JSON file is updated every day at 3am Pacific time.
image

<!--Script for fetching the correct project-->
<script>
    {% assign projects = site.data.github-data | jsonify %}
    let projects = {{ projects }};
    let projectId = '{{ page.identification }}';
    // Search for correct project
    let project = null;
    for(item of projects){
        let itemId = item.id.toString();
        if(itemId == projectId){
            project = item;
            break;
        }
    }
</script>

Adding Languages

Using the project variable defined in the Fetching Correct Project script, we'll loop through the document for the languages used in the project and output them.
image

<!--Script for adding languages to "Languages" Section-->
<script>
    let languagesSection = document.getElementById('languages');
    if(project != null && project.languages.data.length > 0){
        let languages = project.languages.data.join(', ');
        let languagesParagraph = document.createElement('p');
        languagesParagraph.style.display = 'inline';
        let languagesText = document.createTextNode(languages);
        languagesParagraph.appendChild(languagesText);
        languagesSection.appendChild(languagesParagraph);
    } else {
        languagesSection.remove();
    }
</script>

Constructing Team Card

Again, using the project variable defined in the Fetching Correct Project script, we're looping through the contributors list to create miniature cards with their links and Github avatars to append to the project page.

<!--Script for constructing Team Card-->
<script>
    let contributors = document.getElementById('contributors-list');
    if(project != null){
        for(contributor of project.contributors.data){
            let contributorDiv = document.createElement('div');
            contributorDiv.classList.add('contributor-div');

            let contributorProfile = document.createElement('a');
            contributorProfile.classList.add('contributor-link');
            contributorProfile.setAttribute('href', contributor.github_url);
            contributorProfile.setAttribute('target', '_blank');
            let contributorUrl = contributor.github_url.split('/');
            let contributorName = contributorUrl.pop();
            contributorProfile.setAttribute('title', contributorName);

            let contributorImg = document.createElement('img');
            contributorImg.style['border-radius'] = '12px';
            contributorImg.setAttribute('src', contributor.avatar_url);

            contributorProfile.appendChild(contributorImg);
            contributorDiv.appendChild(contributorProfile);
            contributors.appendChild(contributorDiv);
        }
    } else {
        let messageDiv = document.createElement('div');
        messageDiv.classList.add('empty-content-message');
        let messageText = document.createElement('p');
        messageText.appendChild(document.createTextNode('Looks like this project has not connected a GitHub repository yet!'));
        messageDiv.appendChild(messageText);
        contributors.parentNode.appendChild(messageDiv);
        contributors.parentNode.removeChild(contributors);
    }
</script>

Getting Started Drop Down

Creates the 'Getting Started' drop down button, and adjusting its styling.
image

<!--Script for Getting Started drop down functionality-->
<script>
    let dropDownOpen = false;
    function gettingStarted(){
        if(!dropDownOpen){
            dropDownOpen = true;
            let gettingStartedButton = document.getElementsByClassName('getting-started-button')[0];
            gettingStartedButton.style.transform = 'rotate(180deg)';

            let gettingStartedCard = document.getElementById('getting-started-section');
            let maxHeight = gettingStartedCard.children[0].offsetHeight * 1.5; // Adding pixels for good measure and pop up message
            gettingStartedCard.style['max-height'] = maxHeight + 'px';
            gettingStartedCard.style.padding = '30px 30px';
        }
        else {
            dropDownOpen = false;
            let gettingStartedButton = document.getElementsByClassName('getting-started-button')[0];
            gettingStartedButton.style.transform = 'rotate(0deg)';

            let gettingStartedCard = document.getElementById('getting-started-section');
            gettingStartedCard.style['max-height'] = '0px';
            gettingStartedCard.style.padding = '0px 30px';
        }
    }
</script>

Call to Action Message

When the 'Help Make One!' button is clicked, a message will pop out.
image

This code allows the output of this message when a project does not have links for its Getting Started section.

<!--Script for constructing Getting Started call to action message-->
<script>
    let helpGettingStarted = document.getElementById('help-getting-started');
    let textDiv = document.createElement('div');
    textDiv.setAttribute('id', 'help-make-text-section');

    let hflaSlack = document.createElement('a');
    hflaSlack.setAttribute('href', 'https://hackforla.slack.com/archives/C4UM52W93');
    hflaSlack.setAttribute('target', '_blank');
    let hflaSlackText = document.createTextNode('Hack for LA');
    hflaSlack.appendChild(hflaSlackText);

    let projectSlack = document.createElement('a');
    {% for item in page.links %}
        {% if item.name == 'Slack' %}
            projectSlack.setAttribute('href', '{{ item.url }}')
            projectSlack.setAttribute('target', '_blank');
        {% endif %}
    {% endfor %}
    let projectSlackText = document.createTextNode('our');
    projectSlack.appendChild(projectSlackText);

    let message = document.createElement('p');
    message.style.width = '200px';
    let text1 = document.createTextNode('Once you are on the ');
    let text2 = document.createTextNode(' slack channel, please post a note in ');
    let text3 = document.createTextNode(' channel indicating your interest.');

    message.appendChild(text1);
    message.appendChild(hflaSlack);
    message.appendChild(text2);
    message.appendChild(projectSlack);
    message.appendChild(text3);
    textDiv.appendChild(message);
    helpGettingStarted.insertAdjacentElement('afterend', textDiv);

    function helpMakeGuide(){
        let textDiv = document.getElementById('help-make-text-section');
        textDiv.style['min-width'] = '225px';
        textDiv.style.padding = '35px 15px';
    }
</script>

Return to Contents

⚠️ **GitHub.com Fallback** ⚠️