Johan Broddfelt

Topics to categorize posts

I'm not only going to write about my php framework. I want to write about other things as well, but I still want it to be easy to find and follow posts on a specific topic. We have tags but they do not really do the trick. So today we are going to implement a topic to the site.
First of all we set up the database table. Which in this case is really simple.

// Add table topic
CREATE TABLE IF NOT EXISTS `topic` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) COLLATE utf8mb4_bin NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=1;

// Add relation to topic in post
ALTER TABLE `post` ADD `topic_id` INT NOT NULL AFTER `title`, ADD INDEX (`topic_id`);

After adding a set of topics and inserting them into my posts I want to update the menu so that I get a filter on top where I can filter on topic when selecting posts. But first we need to create a Topic class.

// classes/Topic.php

Now I have rewritten the post_menu.php in order to add the topic at the top of the menu.

// views/post/post_menu.php
fetchArray('WHERE publish < '' . date('Y-m-d H:i:s') . '' ORDER BY publish DESC LIMIT 20'); foreach($pList as $item) { ?>
// css/main.css #menu_topic { display: flex; flex-wrap: wrap; line-height: 50px; justify-content: flex-start; align-content: flex-start; margin: 0px !important; padding: 0px !important; margin-left: 0px !important; padding-left: 25px !important; padding-right: 25px !important; margin-right: 0px !important; padding-top: 0px !important; padding-bottom: 0px !important; } .topic_button { cursor: pointer; padding-left: 10px; padding-right: 10px; } .topic_button:hover { background: #GreyNormal; } // js/main.js // Topic menu var topicBtn = document.getElementsByClassName('topic_button'); var i = 0; while (i < topicBtn.length) { addListener(topicBtn[i], 'click', topic_click); i++; } function topic_click(e) { // if id == 0 then show all else hide all var postLink = document.getElementsByClassName('post_link'); var i = 0; while (i < postLink.length) { if (e.target.id === 'topic_0' || hasClass(postLink[i], e.target.id)) { postLink[i].style.display = null; } else { postLink[i].style.display = 'none'; } i++; } };

As you can see the code contains a function called hasClass. So I just going to add three functions that handles classes in the top of my js Framework part.

// js/main.js
// Manage classes in html elements
function hasClass(ele,cls) {
  return !!ele.className.match(new RegExp('(s|^)'+cls+'(s|$)'));
}

function addClass(ele,cls) {
  if (!hasClass(ele,cls)) ele.className += " "+cls;
}

function removeClass(ele,cls) {
  if (hasClass(ele,cls)) {
    var reg = new RegExp('(s|^)'+cls+'(s|$)');
    ele.className=ele.className.replace(reg,' ');
  }
}

I also want to make it easier to follow the posts on a specific topic. So on each post I'm going to add a link to the previous and the next post on that specific topic. First I need to write some code that actually find the related topics. Then I'll add them as links in the bottom of the post.

// classes/post.php
    function getPrev() {
        $qry = 'SELECT id, title '
             . 'FROM post '
             . 'WHERE topic_id=' . $this->topicId . ' '
             . '  AND id<' . $this->id . ' '
             . 'ORDER BY id DESC '
             . 'LIMIT 1';
        $res = Db::query($qry);
        $row = Db::fetch_array($res);
        $obj = new Post();
        $obj->id = $row['id'];
        $obj->title = $row['title'];
        return $obj;
    }
    function getNext() {
        $qry = 'SELECT id, title '
             . 'FROM post '
             . 'WHERE topic_id=' . $this->topicId  . ' '
             . '  AND id>' . $this->id . ' '
             . 'ORDER BY id '
             . 'LIMIT 1';
        $res = Db::query($qry);
        $row = Db::fetch_array($res);
        $obj = new Post();
        $obj->id = $row['id'];
        $obj->title = $row['title'];
        return $obj;
    }

Then I'll just add the links in the post item page.

// view/post/item.php


// css/main.css
.navigation {
  display: flex;
  justify-content: space-between;
  padding-left: 30px;
  padding-right: 30px;
}

- framework, php, categories, software

<< RSSfeed for the masses
Follow using RSS
Administration pages >>

Comment

Name
Mail (Not public)
Send mail updates on new comments
0 comment