Added code chunk viewing and inserting possibility

Signed-off-by: Gergely Polonkai (W00d5t0ck) <polesz@w00d5t0ck.info>
This commit is contained in:
Gergely Polonkai (W00d5t0ck)
2012-09-05 12:59:21 +02:00
parent bcf6368db2
commit a41ddec070
16 changed files with 399 additions and 20 deletions

View File

@@ -13,7 +13,7 @@ use GergelyPolonkai\FrontBundle\Entity\Post;
* Description of AdminController
*
* @author polonkai.gergely
*
*
* @Route("/admin")
*/
class AdminController extends Controller

View File

@@ -5,6 +5,9 @@ namespace GergelyPolonkai\FrontBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use GergelyPolonkai\FrontBundle\Entity\CodeChunk;
/**
* @Route("")
@@ -60,4 +63,21 @@ class DefaultController extends Controller
);
}
}
/**
*
* @param string $slug
* @param string $language
* @return array
*
* @Route("/code-chunk/{language}/{slug}.html", name="GergelyPolonkaiFrontBundle_viewCode")
* @Template
* @ParamConverter("codeChunk", options={"mapping"={"slug"="slug", "language"="language"}})
*/
public function viewCodeAction(CodeChunk $codeChunk)
{
return array(
'code_chunk' => $codeChunk,
);
}
}

View File

@@ -0,0 +1,192 @@
<?php
namespace GergelyPolonkai\FrontBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as GedmoORM;
/**
* Description of CodeChunk
*
* @author polonkai.gergely
*
* @ORM\Entity
* @ORM\Table(name="code_chunks")
*/
class CodeChunk
{
/**
*
* @var integer $id
*
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*/
private $id;
/**
*
* @var string $language
*
* @ORM\Column(type="string", length=20, nullable=false)
*/
private $language;
/**
*
* @var string $title
*
* @ORM\Column(type="string", length=100, nullable=false)
*/
private $title;
/**
*
* @var string $slug
*
* @GedmoORM\Slug(fields={"title"})
* @ORM\Column(type="string", length=100, nullable=false)
*/
private $slug;
/**
*
* @var string $description
*
* @ORM\Column(type="text", nullable=true)
*/
private $description;
/**
*
* @var string $content
*
* @ORM\Column(type="text", nullable=false)
*/
private $content;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set language
*
* @param string $language
* @return CodeChunk
*/
public function setLanguage($language)
{
$this->language = $language;
return $this;
}
/**
* Get language
*
* @return string
*/
public function getLanguage()
{
return $this->language;
}
/**
* Set title
*
* @param string $title
* @return CodeChunk
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set slug
*
* @param string $slug
* @return CodeChunk
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Set description
*
* @param string $description
* @return CodeChunk
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set content
*
* @param string $content
* @return CodeChunk
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* Get content
*
* @return string
*/
public function getContent()
{
return $this->content;
}
}

View File

@@ -167,7 +167,7 @@ class Post
/**
* Set slug
*
* @param string $slug
* @param string $slug
* @return Post
*/
public function setSlug($slug)
@@ -180,7 +180,7 @@ class Post
/**
* Set createdAt
*
* @param \DateTime $createdAt
* @param \DateTime $createdAt
* @return Post
*/
public function setCreatedAt($createdAt)
@@ -189,4 +189,4 @@ class Post
return $this;
}
}
}

View File

@@ -43,14 +43,17 @@ class User implements UserInterface
return $this->name . '(' . $this->username . ')';
}
public function getSalt() {
public function getSalt()
{
return $this->password;
}
public function eraseCredentials() {
public function eraseCredentials()
{
}
public function getRoles() {
public function getRoles()
{
return array('ROLE_ADMIN');
}
@@ -119,6 +122,7 @@ class User implements UserInterface
public function setPassword($password)
{
$this->password = $password;
return $this;
}
@@ -131,4 +135,4 @@ class User implements UserInterface
{
return $this->password;
}
}
}

View File

@@ -6,12 +6,38 @@
Purpose of the stylesheet follows.
*/
.code-chunk {
background-color: #b5b5b5;
padding: 10px;
}
.code-chunk .code-title {
text-indent: 0 !important;
font-size: 120%;
font-weight: bold;
}
.code-chunk .code-description {
border: 1px solid #333;
background-color: #d9d9d9;
padding: 3px;
text-indent: 0 !important;
margin: .5em 0 0 0 !important;
font-size: 75%;
color: #444;
}
.code {
font-family: monospace;
background-color: #333;
padding: 5px;
}
.code-chunk .code {
height: 300px;
overflow: auto;
}
.code * {
font-family: monospace;
color: #b5b5b5;

View File

@@ -10,4 +10,4 @@
<input type="password" name="_password" />
<button type="submit">Login</button>
</form>
{% endblock %}
{% endblock %}

View File

@@ -5,4 +5,4 @@
{{ form_widget(form) }}
<button type="submit">Save</button>
</form>
{% endblock content %}
{% endblock content %}

View File

@@ -0,0 +1,3 @@
<h3>{% if title_links %}<a href="{{ path('GergelyPolonkaiFront_blogViewPost', {year: post.createdAt|date('Y'), month: post.createdAt|date('m'), day: post.createdAt|date('d'), slug: post.slug}) }}">{% endif %}{{ post.title }}{% if title_links %}</a>{% endif %}</h3>
<p class="article-date">{{ post.createdAt|date('m-d-Y :: H:i') }} by {{ post.user.name }}</p>
{{ post.content|insert_code_chunks }}

View File

@@ -1,6 +1,5 @@
{% extends 'GergelyPolonkaiFrontBundle:Default:front_base.html.twig' %}
{% block content %}
<h3>{{ post.title }}</h3>
<p class="article-date">{{ post.createdAt|date('m-d-Y :: H:i') }} by {{ post.user.name }}</p>
{{ post.content|raw }}
{% include 'GergelyPolonkaiFrontBundle:Blog:postViewer.html.twig' with {'post': post, 'title_links': false} %}
{% endblock content %}

View File

@@ -2,8 +2,6 @@
{% block content %}
{% for post in posts %}
<h3><a href="{{ path('GergelyPolonkaiFront_blogViewPost', {year: post.createdAt|date('Y'), month: post.createdAt|date('m'), day: post.createdAt|date('d'), slug: post.slug}) }}">{{ post.title }}</a></h3>
<p class="article-date">{{ post.createdAt|date('m-d-Y :: H:i') }} by {{ post.user.name }}</p>
{{ post.content|raw }}
{% include 'GergelyPolonkaiFrontBundle:Blog:postViewer.html.twig' with {'post': post, 'title_links': true} %}
{% endfor %}
{% endblock content %}

View File

@@ -0,0 +1,11 @@
{% extends 'GergelyPolonkaiFrontBundle:Default:front_base.html.twig' %}
{% block content %}
<h3>{{ code_chunk.title }}</h3>
{{ code_chunk.content|geshi_highlight(code_chunk.language) }}
{% if code_chunk.description %}
<div class="code-description">
{{ code_chunk.description }}
</div>
{% endif %}
{% endblock %}

View File

@@ -13,11 +13,13 @@ use JMS\DiExtraBundle\Annotation as DI;
*/
class CryptEncoder implements PasswordEncoderInterface
{
public function encodePassword($raw, $salt) {
public function encodePassword($raw, $salt)
{
return crypt($raw);
}
public function isPasswordValid($encoded, $raw, $salt) {
public function isPasswordValid($encoded, $raw, $salt)
{
return (crypt($raw, $encoded) === $encoded);
}
}

View File

@@ -0,0 +1,96 @@
<?php
namespace GergelyPolonkai\FrontBundle\Twig;
use Symfony\Bridge\Doctrine\RegistryInterface;
use JMS\DiExtraBundle\Annotation as DI;
use Symfony\Component\Routing\Router;
/**
* Description of CodeChunk
*
* @author polonkai.gergely
*
* @DI\Service
* @DI\Tag("twig.extension")
*/
class CodeChunk extends \Twig_Extension
{
/**
* @var Symfony\Bridge\Doctrine\RegistryInterface $doctrine
*/
private $doctrine;
/**
*
* @var Symfony\Component\Routing\Router $router
*/
private $router;
private $hiliter;
/**
* @DI\InjectParams({
* "doctrine" = @DI\Inject("doctrine"),
* "router" = @DI\Inject("router"),
* "hiliter" = @DI\Inject("gergely_polonkai_geshi.geshi_highlighter")
* })
*/
public function __construct(RegistryInterface $doctrine, Router $router, $hiliter)
{
$this->doctrine = $doctrine;
$this->router = $router;
$this->hiliter = $hiliter;
}
public function getFilters()
{
return array(
'insert_code_chunks' => new \Twig_Filter_Method($this, 'insertCodeChunks', array('is_safe' => array('html'))),
);
}
public function insertCodeChunks($string)
{
$m = array();
$chunkRepo = $this->doctrine->getRepository('GergelyPolonkaiFrontBundle:CodeChunk');
while (
preg_match(
'/\\[\\$ code:([^:]+):([^ ]+) \\$\\]/i',
$string, $m, PREG_OFFSET_CAPTURE)
) {
$start = $m[0][1];
$fullTag = $m[0][0];
$len = strlen($fullTag);
$lang = strtolower($m[1][0]);
$slug = strtolower($m[2][0]);
$replacement = '';
$chunk = $chunkRepo->findOneBy(array('language' => $lang, 'slug' => $slug));
if ($chunk !== null) {
$link = $this->router->generate('GergelyPolonkaiFrontBundle_viewCode', array('language' => $lang, 'slug' => $slug));
$replacement = '<div class="code-chunk">
<p class="code-title"><a href="' . $link . '">' . $chunk->getTitle() . '</a></p>
' . $this->hiliter->geshiFilter($chunk->getContent(), $lang) . "\n";
$description = $chunk->getDescription();
if (($description !== null) && ($description != '')) {
$replacement .= ' <div class="code-description">
' . $description . "
</div>\n";
}
$replacement .= '</div>';
}
$string = substr_replace($string, $replacement, $start, $len);
}
return $string;
}
public function getName()
{
return "code_chunk";
}
}