Build a Stunning Portfolio in Minutes with Python & Bootstrap
Tags: python, bootstrap, opengraph, tutorial
Published: 2023-09-11 16:32:43

I needed a simple way to extract and add snippets created from the [Open Graph](https://ogp.me/) tags (`og:xyz`) of my own articles, published across various websites.The goal was to quickly put together my writing portfolio. The Open Graph snippets (aka _“cards”_), are those good-looking previews visible on social media platforms when you share a link/URL as shown below.

![Open Graph Preview Card](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ayly6xbfq61c40jolrle.png)

I couldn’t find one such tool/script to accomplish my goal. So I decided to write one myself. Follow along for this brief tutorial, or simply use the free portfolio-maker tool directly.

### Prerequisite

* Some familiarity with basic HTML and CSS. Although, the tool will automatically create a portfolio for you if you’re fine with the default theme.
* Familiarity with Python – installing packages and running Python code from the command line.

### Open Graph Tags

Here are some Open Graph tags from an HTML file. These tags are used by the social media platforms to generate attractive previews. 

The Python tool extracts these tags from a website to create a portfolio snippet. It won't be able to create a snippet if these tags are absent.

```html
<meta property="og:title" content="Web Page Title" />
<meta property="og:description" content="Longer description..." />
<meta property="og:image" content="Image URL" />
<meta property="og:url" content="Website/Web-page URL" />
```

### Bootstrap Cards

Since the portfolio needs to be [responsive](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design), this tool uses [Bootstrap](https://getbootstrap.com/) template - it is a ready-made website framework that you can use to quickly and easily create a responsive website. The portfolio-maker tool only uses the CSS part of the framework, not JavaScript. You can include it in the HTML via CDN as shown below -

```html
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" 
rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" 
crossorigin="anonymous">
```

The next important step is to choose the right [card](https://getbootstrap.com/docs/4.0/components/card/) template for the website snippets that you want to include in your portfolio. This is crucial to ensure that your Portfolio looks attractive.  You can choose one such card template here - [23 Bootstrap Snippets](https://bootstrapious.com/p/cards). I have chosen Bootstrap Card Responsive ([HTML + CSS](https://codepen.io/wisnust10/pen/BKjNNR)) template for this tool. Besides a few cosmetic changes, I have added height restrictions in the CSS to ensure that the cards are uniform for all the portfolio snippets.

At the heart of this template, there is a card designed to display a single portfolio item. Additionally, the template makes sure that these cards work well on different devices and screen sizes, even with the images they contain. This means the cards will always resize properly on various screens, including mobile phones (responsive template).

```html
<!-- START: Portfolio Card  -->
<div class="col-xs-12 col-sm-4">
    <div class="card">
        <a class="img-card" href="<url-here>" title="">
            <img src="<image-url-here>" alt=""/>
        </a>
        <div class="card-content">
            <h4 class="card-title">
                <a href="<url-here>" title="">
                    Project/Article Title
                </a>
            </h4>
            <p class="">
                Project/Article description in short...
            </p>
        </div>
        <div class="card-read-more">
            <a href="<url-here>" class="btn btn-outline-info" title="">
                Read More
            </a>
        </div>
    </div>
</div>
<!-- END: Card - Career, beyond ladders… -->
```

### Creating Portfolio Snippets with Python

Essentially, the Python code for this tool works by generating a portfolio card for each provided URL. It uses `BeautifulSoup` (to parse HTML), `Requests` (to make HTTP requests), and `Jinja2` templates (to generate dynamic HTML) to create the portfolio snippets. You can install theses packages with pip:

```python
pip install requests
pip install beautifulsoup4
pip install Jinja2
```

Take a look at this code snippet that extracts Open Graph tags from the web pages. It uses `regex` with `BeautifulSoup` to extract all the Open Graph tags from the HTML. The code further cleans them (removes `og:` part), and returns a simple key-value dictionary of these tags.

```python
def _extract_og_data(self, url: str) -> dict:
    og_tags = dict()
    try:
        resp = requests.get(url)
        if 200 == resp.status_code:
            soup = BeautifulSoup(resp.text, 'html.parser')

            regex = re.compile('.*og:.*')
            og_data = soup.find_all("meta", {"property": regex, "content": True})

            for tag in og_data:
                og_index = tag['property'].index(":") + 1
                _key = tag['property'][og_index:]
                og_tags[_key] = tag['content']
        else:
            logging.warning(f"Invalid response form the site: {resp}")
    except Exception as ex:
        logging.exception(f"Exception: {ex}")
    finally:
        return og_tags
```

The following code snippet invokes the `_extract_og_data(...)` for a list of URLs and creates Open Graph data (a list of dictionaries) for creating the portfolio. The list of URLs is read from the text file: `urls.txt`. 

```python
site_cards = []
for url in urls:
    og_data = self._extract_og_data(url)
    site_cards.append(og_data)
```

### Jinja2 Templates

The portfolio is actually created using a [Jinja](https://jinja.palletsprojects.com/en/3.0.x/templates/) template. Jinja is a Python template engine that offers a cleaner way to make dynamic HTML pages or other text-based documents.

In the code snippet below, the Jinja template generates multiple portfolio cards by iterating over the Open Graph data — `cards`, and substitutes relevant data (title, image, description etc.) in the HTML template.

```html
{% for og_card in cards %}
<!-- START: Card - {{og_card.title}} -->
<div class="col-xs-12 col-sm-4">
    <div class="card">
        <a class="img-card" href="{{og_card.url}}" title="{{og_card.title}}">
            <img src="{{og_card.image}}" alt="Featured Image"/>
        </a>
        <div class="card-content">
            <h4 class="card-title">
                <a href="{{og_card.url}}" title="More...">
                    {{ og_card.title|truncate(30, true) }}
                </a>
            </h4>
            <p class="">
                {{ og_card.description|truncate(160) }}
            </p>
        </div>
        <div class="card-read-more">
            <a href="{{og_card.url}}" class="btn btn-outline-info" title="{{og_card.title}}">
                Read More
            </a>
        </div>
    </div>
</div>
<!-- END: Card - {{og_card.title}} -->
{% endfor %}
```

Lastly, the portfolio generated by the template is saved in a new file. You may edit this file to use your own CSS theme. You can see one such generated portfolio here - [The world of expressions](https://reclusivecoder.com/manish-hatwalne/writings.php).

### Using Portfolio Maker

You can use this tool in two different modes via the command line:

- Portfolio Mode: This mode generates a single portfolio page, complete with HTML and CSS, using the provided list of URLs.

- Snippets Mode: In this mode, the tool creates Bootstrap cards. You can then incorporate this generated HTML into your existing portfolio. This mode is particularly useful when you want to seamlessly add more work samples to your current portfolio.

See this tool in action through the animated GIF below.


![Portfolio Maker](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pf88bpltc2rjziie8jvq.gif)

### Conclusion

An anecdotal joke about developers goes like this: A developer takes 2-3 days to automate a task that could have been finished in 2-3 hours. Well, with this "portfolio-maker", I personify that imaginary developer. :D

However, now that I've built this tool, all I need to do is add new URLs to the urls.txt file and then just run this tool to create the portfolio in just a few seconds. I don't need to worry about putting the correct links, title, description,  image etc.for every new article that I need to add there. ¯\_(ツ)_/¯                 

Do you want to build a stunning portfolio to impress your potential clients? 

Make use of this [portfolio-maker](https://manishh.gumroad.com/l/portfolio-maker), now offered for _**free**_ on Gumroad! Plus, it comes with full code access and a helpful video tutorial. :)

---