Merge branch 'bluditv2' of github.com:dignajar/bludit into bluditv2

This commit is contained in:
Diego 2017-07-19 21:58:44 +02:00
commit 48a4077ebb
56 changed files with 5113 additions and 205 deletions

View File

@ -91,7 +91,7 @@ function checkGet($args)
}
// Bruteforce protection, add IP to blacklist.
$Security->addLoginFail();
$Security->addToBlacklist();
return false;
}

View File

@ -8,27 +8,26 @@
// Functions
// ============================================================================
function checkPost($args)
function checkLogin($args)
{
global $Security;
global $Login;
global $Language;
if($Security->isBlocked()) {
if ($Security->isBlocked()) {
Alert::set($Language->g('IP address has been blocked').'<br>'.$Language->g('Try again in a few minutes'));
return false;
}
// Verify User sanitize the input
if( $Login->verifyUser($_POST['username'], $_POST['password']) ) {
if ($Login->verifyUser($_POST['username'], $_POST['password'])) {
// Renew the token. This token will be the same inside the session for multiple forms.
$Security->generateTokenCSRF();
Redirect::page('dashboard');
return true;
}
// Bruteforce protection, add IP to blacklist.
$Security->addLoginFail();
// Bruteforce protection, add IP to the blacklist
$Security->addToBlacklist();
// Create alert
Alert::set($Language->g('Username or password incorrect'));
@ -44,9 +43,9 @@ function checkPost($args)
// POST Method
// ============================================================================
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
if ($_SERVER['REQUEST_METHOD']=='POST')
{
checkPost($_POST);
checkLogin($_POST);
}
// ============================================================================

View File

@ -83,7 +83,7 @@ if( $_SERVER['REQUEST_METHOD'] == 'POST' )
// ============================================================================
// Main after POST
// ============================================================================
$allPublishedPages = buildAllpages(false);
$allPublishedPages = buildAllpages(true);
// Homepage select options
$homepageOptions = array();

View File

@ -217,6 +217,11 @@ div.dashboard-links h4 {
font-size: 0.8em;
}
#dashboard-hello {
background-color: #FBDF6B;
padding: 20px;
margin-bottom: 8px;
}
/* FORM
---------------------------------------------------------------- */

File diff suppressed because one or more lines are too long

View File

@ -18,6 +18,7 @@
<link rel="stylesheet" type="text/css" href="<?php echo HTML_PATH_ADMIN_THEME.'css/uikit/progress.almost-flat.min.css?version='.BLUDIT_VERSION ?>">
<link rel="stylesheet" type="text/css" href="<?php echo HTML_PATH_ADMIN_THEME.'css/default.css?version='.BLUDIT_VERSION ?>">
<link rel="stylesheet" type="text/css" href="<?php echo HTML_PATH_ADMIN_THEME.'css/jquery.datetimepicker.css?version='.BLUDIT_VERSION ?>">
<link rel="stylesheet" type="text/css" href="<?php echo DOMAIN_CORE_CSS.'font-awesome/font-awesome.min.css?version='.BLUDIT_VERSION ?>">
<!-- Javascript -->
<script charset="utf-8" src="<?php echo HTML_PATH_CORE_JS.'jquery.min.js?version='.BLUDIT_VERSION ?>"></script>
@ -144,6 +145,9 @@ $(document).ready(function() {
<?php
if( Sanitize::pathFile(PATH_ADMIN_VIEWS, $layout['view'].'.php') ) {
include(PATH_ADMIN_VIEWS.$layout['view'].'.php');
} else {
echo '<h1 style="width:100%; text-align:center">Hey!</h1>';
echo '<h2 style="width:100%; text-align:center">Have you seen my ball?</h2>';
}
?>
</div>

View File

@ -13,9 +13,10 @@
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="<?php echo HTML_PATH_ADMIN_THEME.'css/uikit/uikit.almost-flat.min.css?version='.BLUDIT_VERSION ?>">
<link rel="stylesheet" type="text/css" href="<?php echo HTML_PATH_ADMIN_THEME.'css/login.css?version='.BLUDIT_VERSION ?>">
<link rel="stylesheet" type="text/css" href="<?php echo HTML_PATH_CORE_CSS.'font-awesome/font-awesome.min.css?version='.BLUDIT_VERSION ?>">
<!-- Javascript -->
<script charset="utf-8" src="<?php echo HTML_PATH_ADMIN_THEME.'js/jquery.min.js?version='.BLUDIT_VERSION ?>"></script>
<script charset="utf-8" src="<?php echo HTML_PATH_CORE_JS.'jquery.min.js?version='.BLUDIT_VERSION ?>"></script>
<script charset="utf-8" src="<?php echo HTML_PATH_ADMIN_THEME.'js/uikit/uikit.min.js?version='.BLUDIT_VERSION ?>"></script>
<!-- Plugins -->

View File

@ -148,6 +148,4 @@
</div>
</div>

View File

@ -4,7 +4,7 @@
<form method="post" action="" class="uk-form" autocomplete="off">
<input type="hidden" id="jstoken" name="tokenCSRF" value="<?php $Security->printTokenCSRF() ?>">
<input type="hidden" id="jstoken" name="tokenCSRF" value="<?php echo $Security->getTokenCSRF() ?>">
<div class="uk-form-row">
<input name="email" class="uk-width-1-1 uk-form-large" placeholder="<?php $L->p('Email') ?>" type="text">

View File

@ -2,7 +2,7 @@
<form method="post" action="" class="uk-form" autocomplete="off">
<input type="hidden" id="jstoken" name="tokenCSRF" value="<?php $Security->printTokenCSRF() ?>">
<input type="hidden" id="jstoken" name="tokenCSRF" value="<?php echo $Security->getTokenCSRF() ?>">
<div class="uk-form-row">
<input name="username" class="uk-width-1-1 uk-form-large" placeholder="<?php $L->p('Username') ?>" type="text">

View File

@ -50,14 +50,12 @@ else
// User not logged.
// Slug is login.
// Slug is login-email.
if($Url->notFound() || !$Login->isLogged() || ($Url->slug()==='login') || ($Url->slug()==='login-email') )
{
if($Url->notFound() || !$Login->isLogged() || ($Url->slug()==='login') || ($Url->slug()==='login-email') ) {
$layout['controller'] = 'login';
$layout['view'] = 'login';
$layout['template'] = 'login.php';
if($Url->slug()==='login-email')
{
if ($Url->slug()==='login-email') {
$layout['controller'] = 'login-email';
$layout['view'] = 'login-email';
}

View File

@ -57,6 +57,7 @@ define('DB_CATEGORIES', PATH_DATABASES.'categories.php');
define('DB_TAGS', PATH_DATABASES.'tags.php');
define('DB_SYSLOG', PATH_DATABASES.'syslog.php');
define('DB_USERS', PATH_DATABASES.'users.php');
define('DB_SECURITY', PATH_DATABASES.'security.php');
// Log separator
define('LOG_SEP', ' | ');
@ -110,7 +111,7 @@ define('CLI_STATUS', 'published');
define('CLI_USERNAME', 'admin');
// Filename
define('FILENAME', 'index.md');
define('FILENAME', 'index.txt');
// Database date format
define('DB_DATE_FORMAT', 'Y-m-d H:i:s');

View File

@ -100,7 +100,7 @@ if( $dbPages->scheduler() ) {
}
// Generate pages parent tree, only published pages
buildPagesByParent(false);
//buildPagesByParent(true);
// Set home page is the user defined one
if( $Site->homepage() && $Url->whereAmI()==='home' ) {

View File

@ -72,10 +72,9 @@ class dbPages extends dbJSON
}
// Where the data is stored
if($options['inFile']) {
$dataForFile[$field] = Text::firstCharUp($field).': '.$value;
}
else {
if ($options['inFile']) {
$dataForFile[$field] = $this->stylingFieldsForFile($field, $value);
} else {
// Set type
settype($value, gettype($options['value']));
@ -84,7 +83,7 @@ class dbPages extends dbJSON
}
}
if( $climode===false ) {
if ($climode===false) {
// Create the directory
if( Filesystem::mkdir(PATH_PAGES.$key, true) === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to create the directory '.PATH_PAGES.$key);
@ -92,7 +91,7 @@ class dbPages extends dbJSON
}
// Make the index.txt and save the file.
$data = implode("\n", $dataForFile);
$data = implode(PHP_EOL, $dataForFile);
if( file_put_contents(PATH_PAGES.$key.DS.FILENAME, $data) === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to put the content in the file '.FILENAME);
return false;
@ -155,11 +154,9 @@ class dbPages extends dbJSON
$value = $options['value'];
}
// Where the data is stored
if($options['inFile']) {
$dataForFile[$field] = Text::firstCharUp($field).': '.$value;
}
else {
if ($options['inFile']) {
$dataForFile[$field] = $this->stylingFieldsForFile($field, $value);
} else {
// Set type
settype($value, gettype($options['value']));
@ -309,7 +306,7 @@ class dbPages extends dbJSON
// Returns an array with a list of pages
// The database is sorted by date or by position
// (int) $pageNumber, the page number
// (int) $amountOfItems, amount of items to return
// (int) $amountOfItems, amount of items to return, if -1 returns all the items
// (boolean) $onlyPublished, TRUE to return only published pages
public function getList($pageNumber, $amountOfItems, $onlyPublished=true)
{
@ -322,6 +319,10 @@ class dbPages extends dbJSON
// Remove Error page from the list
unset($db['error']);
if($amountOfItems==-1) {
return $db;
}
// The first page number is 1, so the real is 0
$realPageNumber = $pageNumber - 1;
@ -583,6 +584,25 @@ class dbPages extends dbJSON
}
}
private function stylingFieldsForFile($field, $value)
{
// Support for Markdown files, good approach for Github
if (FILENAME==='index.md') {
if ($field==='title') {
return '#Title: '.$value;
} elseif ($field==='content') {
return '---'.PHP_EOL.$value;
} else {
return '<!-- '.Text::firstCharUp($field).': '.$value.' -->';
}
}
// Legacy style of Bludit with index.txt
if ($field==='content') {
return 'Content:'.PHP_EOL.$value;
}
return Text::firstCharUp($field).': '.$value;
}
// ----- OLD

View File

@ -185,19 +185,18 @@ class dbUsers extends dbJSON
return $token;
}
// ---- OLD
// Returns array with the username databases filtered by username, FALSE otherwise
public function getDb($username)
public function getDB($username)
{
if($this->exists($username)) {
$user = $this->db[$username];
return $user;
if ($this->exists($username)) {
return $this->db[$username];
}
return false;
}
// ---- OLD
public function getAll()
{
return $this->db;

View File

@ -149,28 +149,32 @@ function buildPagesFor($for, $categoryKey=false, $tagKey=false)
// Generate the global variable $pagesByParent, defined on 69.pages.php
// (boolean) $allPages, TRUE include all status, FALSE only include published status
function buildPagesByParent($allPages=true) {
function buildPagesByParent($onlyPublished=true) {
global $dbPages;
global $pagesByParent;
global $pagesByParentByKey;
$keys = array_keys($dbPages->db);
// Get DB
$pageNumber = 1;
$amountOfItems = -1;
$db = $dbPages->getList($pageNumber, $amountOfItems, $onlyPublished);
// Get Keys
$keys = array_keys($db);
foreach($keys as $pageKey) {
$page = buildPage($pageKey);
if($page!==false) {
if($allPages || $page->published()) {
$parentKey = $page->parentKey();
// FALSE if the page is parent
if($parentKey===false) {
array_push($pagesByParent[PARENT], $page);
$pagesByParentByKey[PARENT][$page->key()] = $page;
} else {
if( !isset($pagesByParent[$parentKey]) ) {
$pagesByParent[$parentKey] = array();
}
array_push($pagesByParent[$parentKey], $page);
$pagesByParentByKey[$parentKey][$page->key()] = $page;
$parentKey = $page->parentKey();
// FALSE if the page is parent
if($parentKey===false) {
array_push($pagesByParent[PARENT], $page);
$pagesByParentByKey[PARENT][$page->key()] = $page;
} else {
if( !isset($pagesByParent[$parentKey]) ) {
$pagesByParent[$parentKey] = array();
}
array_push($pagesByParent[$parentKey], $page);
$pagesByParentByKey[$parentKey][$page->key()] = $page;
}
}
}
@ -186,17 +190,20 @@ function buildPagesByParent($allPages=true) {
pageKeyN => Page object,
)
*/
function buildAllpages($allPages=true) {
function buildAllpages($onlyPublished=true) {
global $dbPages;
// Get DB
$pageNumber = 1;
$amountOfItems = -1;
$db = $dbPages->getList($pageNumber, $amountOfItems, $onlyPublished);
$tmp = array();
$keys = array_keys($dbPages->db);
$keys = array_keys($db);
foreach($keys as $pageKey) {
$page = buildPage($pageKey);
if($page!==false) {
if($allPages || $page->published()) {
$tmp[$page->key()] = $page;
}
$tmp[$page->key()] = $page;
}
}
return $tmp;

View File

@ -4,7 +4,16 @@ class Log {
public static function set($text, $type=0)
{
error_log('('.BLUDIT_VERSION.')'.$text, $type);
if (is_array($text) ) {
error_log('------------------------', $type);
error_log('Array', $type);
error_log('------------------------', $type);
foreach ($text as $key=>$value) {
error_log($key.'=>'.$value, $type);
}
error_log('------------------------', $type);
}
error_log('('.BLUDIT_VERSION.') ('.$_SERVER['REQUEST_URI'].') '.$text, $type);
}
}

View File

@ -55,13 +55,9 @@
public static function destroy()
{
session_destroy();
unset($_SESSION);
self::$started = false;
Log::set(__METHOD__.LOG_SEP.'Session destroyed.');
return !isset($_SESSION);
}

View File

@ -19,6 +19,26 @@ class Login {
return Session::get('role');
}
// Returns TRUE if the user is logged, FALSE otherwise
public function isLogged()
{
if (Session::get('fingerPrint')===$this->fingerPrint()) {
$username = Session::get('username');
if (!empty($username)) {
return true;
}
else {
Log::set(__METHOD__.LOG_SEP.'Session username empty, destroy the session.');
Session::destroy();
return false;
}
}
Log::set(__METHOD__.LOG_SEP.'FingerPrint are differents. Current fingerPrint: '.Session::get('fingerPrint').' !== Current fingerPrint: '.$this->fingerPrint());
return false;
}
// Set the session for the user logged
public function setLogin($username, $role)
{
Session::set('username', $username);
@ -26,30 +46,12 @@ class Login {
Session::set('fingerPrint', $this->fingerPrint());
Session::set('sessionTime', time());
Log::set(__METHOD__.LOG_SEP.'Set fingerPrint: '.$this->fingerPrint());
}
public function isLogged()
{
if(Session::get('fingerPrint')===$this->fingerPrint())
{
$username = Session::get('username');
if(!empty($username)) {
return true;
}
else {
Log::set(__METHOD__.LOG_SEP.'Session username empty: '.$username);
}
}
else
{
Log::set(__METHOD__.LOG_SEP.'FingerPrint are differents. Session fingerPrint: '.Session::get('fingerPrint').' !== Current fingerPrint: '.$this->fingerPrint());
}
return false;
Log::set(__METHOD__.LOG_SEP.'User logged, fingerprint: '.$this->fingerPrint());
}
// Check if the username and the password are valid
// Returns TRUE if valid and set the session
// Returns FALSE for invalid username or password
public function verifyUser($username, $password)
{
$username = Sanitize::html($username);
@ -58,25 +60,21 @@ class Login {
$username = trim($username);
$password = trim($password);
if(empty($username) || empty($password)) {
if (empty($username) || empty($password)) {
Log::set(__METHOD__.LOG_SEP.'Username or password empty. Username: '.$username.' - Password: '.$password);
return false;
}
$user = $this->dbUsers->getDb($username);
$user = $this->dbUsers->getDB($username);
if($user==false) {
Log::set(__METHOD__.LOG_SEP.'Username does not exist: '.$username);
return false;
}
$passwordHash = sha1($password.$user['salt']);
if($passwordHash === $user['password'])
{
$passwordHash = $this->dbUsers->generatePasswordHash($password, $user['salt']);
if ($passwordHash===$user['password']) {
$this->setLogin($username, $user['role']);
Log::set(__METHOD__.LOG_SEP.'User logged succeeded by username and password - Username: '.$username);
return true;
}
else {
@ -130,27 +128,14 @@ class Login {
return false;
}
public function fingerPrint($random=false)
public function fingerPrint()
{
// User agent
$agent = getenv('HTTP_USER_AGENT');
if(empty($agent)) {
$agent = 'Bludit/1.0 (Mr Nibbler Protocol)';
if (empty($agent)) {
$agent = 'Bludit/2.0 (Mr Nibbler Protocol)';
}
// User IP
if(getenv('HTTP_X_FORWARDED_FOR'))
$ip = getenv('HTTP_X_FORWARDED_FOR');
elseif(getenv('HTTP_CLIENT_IP'))
$ip = getenv('HTTP_CLIENT_IP');
else
$ip = getenv('REMOTE_ADDR');
if($random) {
return sha1(mt_rand().$agent.$ip);
}
// DEBUG: Ver CLIENT IP, hay veces que retorna la ip ::1 y otras 127.0.0.1
return sha1($agent);
}

View File

@ -24,8 +24,8 @@ class Page {
}
$tmp = 0;
$lines = file($filePath);
foreach($lines as $lineNumber=>$line) {
$file = file($filePath);
foreach($file as $lineNumber=>$line) {
// Split the line in 2 parts, limiter by :
$parts = explode(':', $line, 2);
@ -60,20 +60,15 @@ class Page {
}
// Process the content
if($tmp!==0) {
if ($tmp!==0) {
// Next line after "Content:" or "---"
$tmp++;
// Remove lines after Content
$output = array_slice($lines, $tmp);
// Get all lines after "Content:" or "---"
$content = array_slice($file, $tmp);
if( !empty($parts[1]) ) {
array_unshift($output, "\n");
array_unshift($output, $parts[1]);
}
$implode = implode($output);
$this->vars['contentRaw'] = $implode;
// Join lines in one variable, this is RAW content from file
$this->vars['contentRaw'] = implode($content);
}
return true;

View File

@ -1,9 +1,8 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
<?php defined('BLUDIT') or die('Bludit Badass CMS.');
class Security extends dbJSON
{
private $dbFields = array(
'key1'=>'Where we go we dont need roads',
'minutesBlocked'=>5,
'numberFailuresAllowed'=>10,
'blackList'=>array()
@ -11,51 +10,34 @@ class Security extends dbJSON
function __construct()
{
parent::__construct(PATH_DATABASES.'security.php');
parent::__construct(DB_SECURITY);
}
// Authentication key
// --------------------------------------------------------------------
public function key1()
{
return $this->db['key1'];
}
// ====================================================
// TOKEN FOR CSRF
// ====================================================
// Generate and save the token in Session.
// Generate and save the token in Session
public function generateTokenCSRF()
{
$token = Text::randomText(8);
$token = sha1($token);
Log::set(__METHOD__.LOG_SEP.'New tokenCSRF was generated '.$token);
$token = sha1( uniqid().time() );
Session::set('tokenCSRF', $token);
Log::set('New Token CSRF: '.$token);
}
// Validate the token.
// Validate the token
public function validateTokenCSRF($token)
{
$sessionToken = Session::get('tokenCSRF');
$sessionToken = $this->getTokenCSRF();
return ( !empty($sessionToken) && ($sessionToken===$token) );
}
// Returns the token.
// Returns the token
public function getTokenCSRF()
{
return Session::get('tokenCSRF');
}
public function printTokenCSRF()
{
echo Session::get('tokenCSRF');
}
// ====================================================
// BRUTE FORCE PROTECTION
// ====================================================
@ -64,7 +46,7 @@ class Security extends dbJSON
{
$ip = $this->getUserIp();
if(!isset($this->db['blackList'][$ip])) {
if (!isset($this->db['blackList'][$ip])) {
return false;
}
@ -73,51 +55,42 @@ class Security extends dbJSON
$numberFailures = $userBlack['numberFailures'];
$lastFailure = $userBlack['lastFailure'];
// Check if the IP is expired, then is not blocked.
if($currentTime > $lastFailure + ($this->db['minutesBlocked']*60)) {
// Check if the IP is expired, then is not blocked
if ($currentTime > $lastFailure + ($this->db['minutesBlocked']*60)) {
return false;
}
// The IP has more failures than number of failures, then the IP is blocked.
if($numberFailures >= $this->db['numberFailuresAllowed']) {
// The IP has more failures than number of failures, then the IP is blocked
if ($numberFailures >= $this->db['numberFailuresAllowed']) {
Log::set(__METHOD__.LOG_SEP.'IP Blocked:'.$ip);
return true;
}
// Otherwise the IP is not blocked.
// Otherwise the IP is not blocked
return false;
}
public function addLoginFail()
// Add or update the current client IP on the blacklist
public function addToBlacklist()
{
$ip = $this->getUserIp();
$currentTime = time();
$numberFailures = 1;
if(isset($this->db['blackList'][$ip]))
{
if (isset($this->db['blackList'][$ip])) {
$userBlack = $this->db['blackList'][$ip];
$lastFailure = $userBlack['lastFailure'];
// Check if the IP is expired, then renew the number of failures.
if($currentTime <= $lastFailure + ($this->db['minutesBlocked']*60))
{
// Check if the IP is expired, then renew the number of failures
if($currentTime <= $lastFailure + ($this->db['minutesBlocked']*60)) {
$numberFailures = $userBlack['numberFailures'];
$numberFailures = $numberFailures + 1;
}
}
$this->db['blackList'][$ip] = array('lastFailure'=>$currentTime, 'numberFailures'=>$numberFailures);
Log::set(__METHOD__.LOG_SEP.'Blacklist, IP:'.$ip.', Number of failures:'.$numberFailures);
// Save the database
if( $this->save() === false ) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.');
return false;
}
return true;
return $this->save();
}
public function getNumberFailures($ip=null)
@ -134,14 +107,13 @@ class Security extends dbJSON
public function getUserIp()
{
// User IP
if(getenv('HTTP_X_FORWARDED_FOR'))
if (getenv('HTTP_X_FORWARDED_FOR')) {
$ip = getenv('HTTP_X_FORWARDED_FOR');
elseif(getenv('HTTP_CLIENT_IP'))
} elseif (getenv('HTTP_CLIENT_IP')) {
$ip = getenv('HTTP_CLIENT_IP');
else
} else {
$ip = getenv('REMOTE_ADDR');
}
return $ip;
}
}

View File

@ -3,7 +3,7 @@
{
"native": "Deutsch (Schweiz)",
"english-name": "German",
"last-update": "2016-09-28",
"last-update": "2017-07-10",
"author": "Clickwork",
"email": "egoetschel@clickwork.ch",
"website": "https://clickwork.ch"
@ -236,5 +236,21 @@
"сurrent-status" : "Status",
"disable-the-user" : "Benutzer deaktivieren",
"add-a-new-page": "Eine neue Seite hinzufügen",
"add-a-new-post": "Einen neuen Beitrag hinzufügen"
"add-a-new-post": "Einen neuen Beitrag hinzufügen",
"save-as-draft": "Als Entwurf speichern",
"categories": "Kategorien",
"add-a-new-category": "Eine neue Kategorie hinzufügen",
"new-category": "Neue Katgeorie",
"slug": "slug",
"edit-category": "Kategorie bearbeiten",
"new-theme-configured": "New theme configured",
"plugin-configured": "Plugin configured",
"new-category-created": "New category created",
"new-page-created": "New page created",
"page-deleted": "Page deleted",
"page-edited": "Page edited",
"user-edited": "User edited",
"changes-on-settings": "Changes on settings",
"plugin-installed": "Plugin installed",
"user-password-changed": "User password changed"
}

View File

@ -9,6 +9,12 @@
"website": ""
},
"installer-page-about-content": "The about page is an important and powerful tool for potential clients and partners. For those who wonder who is behind the website, your About page is the first source of information. \n Change this page's content on the admin panel, manage, pages and click on the about page.",
"installer-page-error-content": "Opps, page not found, sorry!",
"page-not-found": "Page not found",
"about-your-site-or-yourself": "About your site or yourself",
"welcome-to-bludit": "Welcome to Bludit",
"username": "Username",
"password": "Password",
"confirm-password": "Confirm Password",
@ -215,7 +221,7 @@
"the-about-page-is-very-important": "The about page is an important and powerful tool for potential clients and partners. For those who wonder who is behind the website, your About page is the first source of information.",
"change-this-pages-content-on-the-admin-panel": "Change this page's content on the admin panel, manage, pages and click on the about page.",
"about-your-site-or-yourself": "About your site or yourself",
"welcome-to-bludit": "Welcome to Bludit",
"site-information": "Site information",
"date-and-time-formats": "Date and time formats",

View File

@ -2,6 +2,6 @@
"plugin-data":
{
"name": "About",
"description": "Little description about your site or yourself."
"description": "Shows a little description about your site or yourself."
}
}

View File

@ -3,7 +3,7 @@
"email": "",
"website": "https://plugins.bludit.com",
"version": "2.0",
"releaseDate": "2017-05-26",
"releaseDate": "2017-06-15",
"license": "MIT",
"compatible": "2.0",
"notes": ""

View File

@ -3,8 +3,8 @@
"email": "",
"website": "https://plugins.bludit.com",
"version": "2.0",
"releaseDate": "2017-07-07",
"releaseDate": "2017-06-15",
"license": "MIT",
"compatible": "2.0",
"notes": ""
}
}

View File

@ -3,7 +3,7 @@
"email": "",
"website": "https://plugins.bludit.com",
"version": "2.0",
"releaseDate": "2017-05-26",
"releaseDate": "2017-06-15",
"license": "MIT",
"compatible": "2.0",
"notes": ""

View File

@ -3,7 +3,7 @@
"email": "",
"website": "https://plugins.bludit.com",
"version": "2.0",
"releaseDate": "2017-05-26",
"releaseDate": "2017-06-15",
"license": "MIT",
"compatible": "2.0",
"notes": ""

View File

@ -8,4 +8,4 @@
"home-page": "Home page",
"show-home-link": "Show home link",
"amount-of-items": "Amount of items"
}
}

View File

@ -3,7 +3,7 @@
"email": "",
"website": "https://plugins.bludit.com",
"version": "2.0",
"releaseDate": "2017-05-26",
"releaseDate": "2017-06-15",
"license": "MIT",
"compatible": "2.0",
"notes": ""

View File

@ -6,7 +6,7 @@ class pluginLinks extends Plugin {
{
// JSON database
$jsondb = json_encode(array(
'Bludit'=>'https://bludit.com',
'Bludit'=>'https://www.bludit.com',
'Donate'=>'https://paypal.me/bludit'
));

View File

@ -14,11 +14,13 @@ class pluginSitemap extends Plugin {
$xml .= '<loc>'.$Site->url().'</loc>';
$xml .= '</url>';
// Get keys of pages
$keys = $dbPages->db;
unset($keys['error']);
$keys = array_keys($keys);
// Get DB
$pageNumber = 1;
$amountOfItems = -1;
$onlyPublished = true;
$db = $dbPages->getList($pageNumber, $amountOfItems, $onlyPublished);
$keys = array_keys($db);
foreach($keys as $pageKey) {
// Create the page object from the page key
$page = buildPage($pageKey);

View File

@ -0,0 +1,187 @@
body {
padding-top: 0;
background: #F7F7F7;
color: #333;
}
a {
border: none;
}
a:hover {
border-bottom: 1px dotted rgba(160, 160, 160, 0.65)
}
h1, h2, h3, h4, h5, h6 {
text-transform: none;
letter-spacing: 0;
font-weight: normal;
margin-bottom: 0.8em;
}
h1 {
font-size: 1.5em;
}
h2 {
font-size: 1.4em;
}
h3 {
font-size: 1.3em;
}
h4 {
font-size: 1.2em;
}
h5 {
font-size: 1.1em;
}
h6 {
font-size: 1em;
}
p {
margin-bottom: 1.3em;
}
code {
border: 0;
color: #333;
margin: 0;
font-weight: bold;
}
pre code {
border: 1px solid #ffcb94;
font-weight: normal !important;
overflow-x: auto;
}
#main {
max-width: 980px;
}
#header {
background-color: #f7f7f7;
border-bottom: 0;
}
#header h1 {
font-size: 1.4em;
font-weight: lighter;
}
#header .links {
border-left: 0;
}
#header .main ul li {
border-left: 0;
}
#header .main ul li > a {
color: #2672ec;
}
header p {
text-transform: none;
letter-spacing: 0;
font-size: 0.9em;
}
#menu .links > li a h3 {
font-size: 1em;
margin-bottom: 0;
}
#intro header h2 {
font-weight: lighter;
margin-bottom: 0;
}
#intro header p {
font-size: 1em;
}
.post {
border: 0;
}
.post a {
color: #2672ec;
}
.post > header {
border-bottom-color: #F7F7F7;
margin-bottom: 1.3em;
}
.post > header .meta {
padding: 0.5em 3em 0.3em;
border-left: 0;
}
.post > header .title {
padding: 0.5em 3em 0.3em;
}
.post > header .title h1 {
font-size: 2em;
font-weight: normal;
margin-bottom: 5px;
}
.post > header .title h1 a {
color: #3c3b3b;
}
.post > footer .stats {
margin: 0;
}
.post > footer .actions {
margin: 0;
}
blockquote p {
margin: 10px 0;
}
.author .name {
letter-spacing: 0.05em;
}
#sidebar {
margin-top: 2.2em;
min-width: 0;
}
.plugin > h2 {
font-weight: normal !important;
text-transform: uppercase;
}
.plugin ul {
list-style: none !important;
padding: 0 !important;
}
.plugin li {
padding: 0 !important;
}
.plugin-pages ul.children {
margin: 0 0 0 10px;
}
.plugin-pages li.parent {
margin: 15px 0;
}
/* Only for Plugin tags */
.plugin-tags li {
text-transform: capitalize;
}

View File

@ -0,0 +1,72 @@
/*
Future Imperfect by HTML5 UP
html5up.net | @n33co
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
*/
/* Button */
input[type="submit"],
input[type="reset"],
input[type="button"],
button,
.button {
border: solid 1px #dedede;
}
/* Form */
input[type="text"],
input[type="password"],
input[type="email"],
input[type="tel"],
select,
textarea {
border: solid 1px #dedede;
}
/* Post */
.post {
border: solid 1px #dedede;
}
.post > header {
border-bottom: solid 1px #dedede;
}
/* Mini Post */
.mini-post {
border: solid 1px #dedede;
}
/* Header */
#header {
border-bottom: solid 1px #dedede;
}
#header .links {
border-left: solid 1px #dedede;
}
#header .main ul li {
border-left: solid 1px #dedede;
}
/* Sidebar */
#sidebar > * {
border-top: solid 1px #dedede;
}
/* Menu */
#menu {
border-left: solid 1px #dedede;
}
#menu > * {
border-top: solid 1px #dedede;
}

View File

@ -0,0 +1,123 @@
/*
Future Imperfect by HTML5 UP
html5up.net | @n33co
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
*/
/* List */
ul.posts article:after {
clear: both;
content: '';
display: block;
}
ul.posts article .image {
display: table-cell;
vertical-align: top;
}
ul.posts article header {
display: table-cell;
padding-right: 1em;
vertical-align: top;
}
/* Author */
.author .name {
display: inline-block;
vertical-align: middle;
}
.author img {
display: inline-block;
vertical-align: middle;
}
/* Post */
.post:after {
clear: both;
content: '';
display: block;
}
.post > header:after {
clear: both;
content: '';
display: block;
}
.post > header .title {
display: table-cell;
vertical-align: top;
width: 65%;
}
.post > header .meta {
display: table-cell;
vertical-align: top;
width: 30%;
}
.post > footer:after {
clear: both;
content: '';
display: block;
}
.post > footer .actions {
display: inline-block;
}
.post > footer .stats {
display: inline-block;
margin-left: 2em;
}
/* Mini Post */
.mini-post .image {
display: block;
}
/* Header */
#header:after {
clear: both;
content: '';
display: block;
}
#header h1 {
float: left;
}
#header .links {
float: left;
}
#header .main {
position: absolute;
right: 0;
top: 0;
}
/* Wrapper */
/* Sidebar */
#sidebar {
display: table-cell;
margin-right: 0;
padding-right: 3em;
vertical-align: top;
}
/* Main */
#main {
display: table-cell;
vertical-align: top;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
/*
HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x<style>article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}</style>";
c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="<xyz></xyz>";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video",version:"3.6.2",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment();
for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d<h;d++)c.createElement(e[d]);return c}};l.html5=e;q(f)})(this,document);

View File

@ -0,0 +1,6 @@
/*! Respond.js v1.4.2: min/max-width media query polyfill
* Copyright 2014 Scott Jehl
* Licensed under MIT
* http://j.mp/respondjs */
!function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){v(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},g=function(a){return a.replace(c.regex.minmaxwh,"").match(c.regex.other)};if(c.ajax=f,c.queue=d,c.unsupportedmq=g,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,comments:/\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,maxw:/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,minmaxwh:/\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,other:/\([^\)]*\)/g},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var h,i,j,k=a.document,l=k.documentElement,m=[],n=[],o=[],p={},q=30,r=k.getElementsByTagName("head")[0]||l,s=k.getElementsByTagName("base")[0],t=r.getElementsByTagName("link"),u=function(){var a,b=k.createElement("div"),c=k.body,d=l.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=k.createElement("body"),c.style.background="none"),l.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&l.insertBefore(c,l.firstChild),a=b.offsetWidth,f?l.removeChild(c):c.removeChild(b),l.style.fontSize=d,e&&(c.style.fontSize=e),a=j=parseFloat(a)},v=function(b){var c="clientWidth",d=l[c],e="CSS1Compat"===k.compatMode&&d||k.body[c]||d,f={},g=t[t.length-1],p=(new Date).getTime();if(b&&h&&q>p-h)return a.clearTimeout(i),i=a.setTimeout(v,q),void 0;h=p;for(var s in m)if(m.hasOwnProperty(s)){var w=m[s],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?j||u():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?j||u():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(n[w.rules]))}for(var C in o)o.hasOwnProperty(C)&&o[C]&&o[C].parentNode===r&&r.removeChild(o[C]);o.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=k.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,r.insertBefore(E,g.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(k.createTextNode(F)),o.push(E)}},w=function(a,b,d){var e=a.replace(c.regex.comments,"").replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},i=!f&&d;b.length&&(b+="/"),i&&(f=1);for(var j=0;f>j;j++){var k,l,o,p;i?(k=d,n.push(h(a))):(k=e[j].match(c.regex.findStyles)&&RegExp.$1,n.push(RegExp.$2&&h(RegExp.$2))),o=k.split(","),p=o.length;for(var q=0;p>q;q++)l=o[q],g(l)||m.push({media:l.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:n.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}v()},x=function(){if(d.length){var b=d.shift();f(b.href,function(c){w(c,b.href,b.media),p[b.href]=!0,a.setTimeout(function(){x()},0)})}},y=function(){for(var b=0;b<t.length;b++){var c=t[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!p[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(w(c.styleSheet.rawCssText,e,f),p[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!s||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}x()};y(),c.update=y,c.getEmValue=u,a.addEventListener?a.addEventListener("resize",b,!1):a.attachEvent&&a.attachEvent("onresize",b)}}(this);

View File

@ -0,0 +1,115 @@
/*
Future Imperfect by HTML5 UP
html5up.net | @n33co
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
*/
(function($) {
skel.breakpoints({
xlarge: '(max-width: 1680px)',
large: '(max-width: 1280px)',
medium: '(max-width: 980px)',
small: '(max-width: 736px)',
xsmall: '(max-width: 480px)'
});
$(function() {
var $window = $(window),
$body = $('body'),
$menu = $('#menu'),
$sidebar = $('#sidebar'),
$main = $('#main');
// Disable animations/transitions until the page has loaded.
$body.addClass('is-loading');
$window.on('load', function() {
window.setTimeout(function() {
$body.removeClass('is-loading');
}, 100);
});
// Fix: Placeholder polyfill.
$('form').placeholder();
// Prioritize "important" elements on medium.
skel.on('+medium -medium', function() {
$.prioritize(
'.important\\28 medium\\29',
skel.breakpoint('medium').active
);
});
// IE<=9: Reverse order of main and sidebar.
if (skel.vars.IEVersion <= 9)
$main.insertAfter($sidebar);
// Menu.
$menu
.appendTo($body)
.panel({
delay: 500,
hideOnClick: true,
hideOnSwipe: true,
resetScroll: true,
resetForms: true,
side: 'right',
target: $body,
visibleClass: 'is-menu-visible'
});
// Search (header).
var $search = $('#search'),
$search_input = $search.find('input');
$body
.on('click', '[href="#search"]', function(event) {
event.preventDefault();
// Not visible?
if (!$search.hasClass('visible')) {
// Reset form.
$search[0].reset();
// Show.
$search.addClass('visible');
// Focus input.
$search_input.focus();
}
});
$search_input
.on('keydown', function(event) {
if (event.keyCode == 27)
$search_input.blur();
})
.on('blur', function() {
window.setTimeout(function() {
$search.removeClass('visible');
}, 100);
});
// Intro.
var $intro = $('#intro');
// Move to main on <=large, back to sidebar on >large.
skel
.on('+large', function() {
$intro.prependTo($main);
})
.on('-large', function() {
$intro.prependTo($sidebar);
});
});
})(jQuery);

2
bl-themes/diego/assets/js/skel.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,587 @@
(function($) {
/**
* Generate an indented list of links from a nav. Meant for use with panel().
* @return {jQuery} jQuery object.
*/
$.fn.navList = function() {
var $this = $(this);
$a = $this.find('a'),
b = [];
$a.each(function() {
var $this = $(this),
indent = Math.max(0, $this.parents('li').length - 1),
href = $this.attr('href'),
target = $this.attr('target');
b.push(
'<a ' +
'class="link depth-' + indent + '"' +
( (typeof target !== 'undefined' && target != '') ? ' target="' + target + '"' : '') +
( (typeof href !== 'undefined' && href != '') ? ' href="' + href + '"' : '') +
'>' +
'<span class="indent-' + indent + '"></span>' +
$this.text() +
'</a>'
);
});
return b.join('');
};
/**
* Panel-ify an element.
* @param {object} userConfig User config.
* @return {jQuery} jQuery object.
*/
$.fn.panel = function(userConfig) {
// No elements?
if (this.length == 0)
return $this;
// Multiple elements?
if (this.length > 1) {
for (var i=0; i < this.length; i++)
$(this[i]).panel(userConfig);
return $this;
}
// Vars.
var $this = $(this),
$body = $('body'),
$window = $(window),
id = $this.attr('id'),
config;
// Config.
config = $.extend({
// Delay.
delay: 0,
// Hide panel on link click.
hideOnClick: false,
// Hide panel on escape keypress.
hideOnEscape: false,
// Hide panel on swipe.
hideOnSwipe: false,
// Reset scroll position on hide.
resetScroll: false,
// Reset forms on hide.
resetForms: false,
// Side of viewport the panel will appear.
side: null,
// Target element for "class".
target: $this,
// Class to toggle.
visibleClass: 'visible'
}, userConfig);
// Expand "target" if it's not a jQuery object already.
if (typeof config.target != 'jQuery')
config.target = $(config.target);
// Panel.
// Methods.
$this._hide = function(event) {
// Already hidden? Bail.
if (!config.target.hasClass(config.visibleClass))
return;
// If an event was provided, cancel it.
if (event) {
event.preventDefault();
event.stopPropagation();
}
// Hide.
config.target.removeClass(config.visibleClass);
// Post-hide stuff.
window.setTimeout(function() {
// Reset scroll position.
if (config.resetScroll)
$this.scrollTop(0);
// Reset forms.
if (config.resetForms)
$this.find('form').each(function() {
this.reset();
});
}, config.delay);
};
// Vendor fixes.
$this
.css('-ms-overflow-style', '-ms-autohiding-scrollbar')
.css('-webkit-overflow-scrolling', 'touch');
// Hide on click.
if (config.hideOnClick) {
$this.find('a')
.css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');
$this
.on('click', 'a', function(event) {
var $a = $(this),
href = $a.attr('href'),
target = $a.attr('target');
if (!href || href == '#' || href == '' || href == '#' + id)
return;
// Cancel original event.
event.preventDefault();
event.stopPropagation();
// Hide panel.
$this._hide();
// Redirect to href.
window.setTimeout(function() {
if (target == '_blank')
window.open(href);
else
window.location.href = href;
}, config.delay + 10);
});
}
// Event: Touch stuff.
$this.on('touchstart', function(event) {
$this.touchPosX = event.originalEvent.touches[0].pageX;
$this.touchPosY = event.originalEvent.touches[0].pageY;
})
$this.on('touchmove', function(event) {
if ($this.touchPosX === null
|| $this.touchPosY === null)
return;
var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX,
diffY = $this.touchPosY - event.originalEvent.touches[0].pageY,
th = $this.outerHeight(),
ts = ($this.get(0).scrollHeight - $this.scrollTop());
// Hide on swipe?
if (config.hideOnSwipe) {
var result = false,
boundary = 20,
delta = 50;
switch (config.side) {
case 'left':
result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta);
break;
case 'right':
result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
break;
case 'top':
result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta);
break;
case 'bottom':
result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta));
break;
default:
break;
}
if (result) {
$this.touchPosX = null;
$this.touchPosY = null;
$this._hide();
return false;
}
}
// Prevent vertical scrolling past the top or bottom.
if (($this.scrollTop() < 0 && diffY < 0)
|| (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {
event.preventDefault();
event.stopPropagation();
}
});
// Event: Prevent certain events inside the panel from bubbling.
$this.on('click touchend touchstart touchmove', function(event) {
event.stopPropagation();
});
// Event: Hide panel if a child anchor tag pointing to its ID is clicked.
$this.on('click', 'a[href="#' + id + '"]', function(event) {
event.preventDefault();
event.stopPropagation();
config.target.removeClass(config.visibleClass);
});
// Body.
// Event: Hide panel on body click/tap.
$body.on('click touchend', function(event) {
$this._hide(event);
});
// Event: Toggle.
$body.on('click', 'a[href="#' + id + '"]', function(event) {
event.preventDefault();
event.stopPropagation();
config.target.toggleClass(config.visibleClass);
});
// Window.
// Event: Hide on ESC.
if (config.hideOnEscape)
$window.on('keydown', function(event) {
if (event.keyCode == 27)
$this._hide(event);
});
return $this;
};
/**
* Apply "placeholder" attribute polyfill to one or more forms.
* @return {jQuery} jQuery object.
*/
$.fn.placeholder = function() {
// Browser natively supports placeholders? Bail.
if (typeof (document.createElement('input')).placeholder != 'undefined')
return $(this);
// No elements?
if (this.length == 0)
return $this;
// Multiple elements?
if (this.length > 1) {
for (var i=0; i < this.length; i++)
$(this[i]).placeholder();
return $this;
}
// Vars.
var $this = $(this);
// Text, TextArea.
$this.find('input[type=text],textarea')
.each(function() {
var i = $(this);
if (i.val() == ''
|| i.val() == i.attr('placeholder'))
i
.addClass('polyfill-placeholder')
.val(i.attr('placeholder'));
})
.on('blur', function() {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
return;
if (i.val() == '')
i
.addClass('polyfill-placeholder')
.val(i.attr('placeholder'));
})
.on('focus', function() {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
return;
if (i.val() == i.attr('placeholder'))
i
.removeClass('polyfill-placeholder')
.val('');
});
// Password.
$this.find('input[type=password]')
.each(function() {
var i = $(this);
var x = $(
$('<div>')
.append(i.clone())
.remove()
.html()
.replace(/type="password"/i, 'type="text"')
.replace(/type=password/i, 'type=text')
);
if (i.attr('id') != '')
x.attr('id', i.attr('id') + '-polyfill-field');
if (i.attr('name') != '')
x.attr('name', i.attr('name') + '-polyfill-field');
x.addClass('polyfill-placeholder')
.val(x.attr('placeholder')).insertAfter(i);
if (i.val() == '')
i.hide();
else
x.hide();
i
.on('blur', function(event) {
event.preventDefault();
var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
if (i.val() == '') {
i.hide();
x.show();
}
});
x
.on('focus', function(event) {
event.preventDefault();
var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']');
x.hide();
i
.show()
.focus();
})
.on('keypress', function(event) {
event.preventDefault();
x.val('');
});
});
// Events.
$this
.on('submit', function() {
$this.find('input[type=text],input[type=password],textarea')
.each(function(event) {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
i.attr('name', '');
if (i.val() == i.attr('placeholder')) {
i.removeClass('polyfill-placeholder');
i.val('');
}
});
})
.on('reset', function(event) {
event.preventDefault();
$this.find('select')
.val($('option:first').val());
$this.find('input,textarea')
.each(function() {
var i = $(this),
x;
i.removeClass('polyfill-placeholder');
switch (this.type) {
case 'submit':
case 'reset':
break;
case 'password':
i.val(i.attr('defaultValue'));
x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
if (i.val() == '') {
i.hide();
x.show();
}
else {
i.show();
x.hide();
}
break;
case 'checkbox':
case 'radio':
i.attr('checked', i.attr('defaultValue'));
break;
case 'text':
case 'textarea':
i.val(i.attr('defaultValue'));
if (i.val() == '') {
i.addClass('polyfill-placeholder');
i.val(i.attr('placeholder'));
}
break;
default:
i.val(i.attr('defaultValue'));
break;
}
});
});
return $this;
};
/**
* Moves elements to/from the first positions of their respective parents.
* @param {jQuery} $elements Elements (or selector) to move.
* @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations.
*/
$.prioritize = function($elements, condition) {
var key = '__prioritize';
// Expand $elements if it's not already a jQuery object.
if (typeof $elements != 'jQuery')
$elements = $($elements);
// Step through elements.
$elements.each(function() {
var $e = $(this), $p,
$parent = $e.parent();
// No parent? Bail.
if ($parent.length == 0)
return;
// Not moved? Move it.
if (!$e.data(key)) {
// Condition is false? Bail.
if (!condition)
return;
// Get placeholder (which will serve as our point of reference for when this element needs to move back).
$p = $e.prev();
// Couldn't find anything? Means this element's already at the top, so bail.
if ($p.length == 0)
return;
// Move element to top of parent.
$e.prependTo($parent);
// Mark element as moved.
$e.data(key, $p);
}
// Moved already?
else {
// Condition is true? Bail.
if (condition)
return;
$p = $e.data(key);
// Move element back to its original location (using our placeholder).
$e.insertAfter($p);
// Unmark element as moved.
$e.removeData(key);
}
});
};
})(jQuery);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1005 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

47
bl-themes/diego/index.php Normal file
View File

@ -0,0 +1,47 @@
<!DOCTYPE HTML>
<html>
<head>
<!-- Include HTML meta tags -->
<?php include(THEME_DIR_PHP.'head.php') ?>
</head>
<body>
<div id="wrapper">
<div id="main">
<?php
if( ($Url->whereAmI()=='home') || ($Url->whereAmI()=='tag') || ($Url->whereAmI()=='blog') )
{
include(THEME_DIR_PHP.'home.php');
}
elseif($Url->whereAmI()=='post')
{
include(THEME_DIR_PHP.'post.php');
}
elseif($Url->whereAmI()=='page')
{
include(THEME_DIR_PHP.'page.php');
}
?>
</div>
<!-- Sidebar -->
<section id="sidebar">
<?php include(THEME_DIR_PHP.'sidebar.php') ?>
</section>
</div>
<!-- Scripts -->
<?php Theme::jquery() ?>
<script src="<?php echo HTML_PATH_THEME ?>assets/js/skel.min.js"></script>
<script src="<?php echo HTML_PATH_THEME ?>assets/js/util.js"></script>
<!--[if lte IE 8]><script src="<?php echo HTML_PATH_THEME ?>assets/js/ie/respond.min.js"></script><![endif]-->
<script src="<?php echo HTML_PATH_THEME ?>assets/js/main.js"></script>
<!-- Plugins Site Body End -->
<?php Theme::plugins('siteBodyEnd') ?>
</body>
</html>

View File

@ -0,0 +1,7 @@
{
"theme-data":
{
"name": "diego",
"description": "Minimalist and very responsive theme, developed by @n33co, adapted and modified for Bludit."
}
}

View File

@ -0,0 +1,7 @@
{
"theme-data":
{
"name": "diego",
"description": "Minimalista y a su vez altamente adaptable para todo tipo de pantallas, desarrollado por @n33co, adaptado y modificado para Bludit."
}
}

View File

@ -0,0 +1,10 @@
{
"author": "n33co",
"email": "",
"website": "http://html5up.net",
"version": "1.4",
"releaseDate": "2016-05-20",
"license": "CCA 3.0",
"compatible": "1.5beta",
"notes": ""
}

View File

@ -0,0 +1,28 @@
<?php
Theme::charset('utf-8');
Theme::viewport('width=device-width, initial-scale=1');
Theme::title();
Theme::description();
Theme::favicon('favicon.png');
?>
<!--[if lte IE 8]><script src="<?php echo HTML_PATH_THEME ?>assets/js/ie/html5shiv.js"></script><![endif]-->
<link rel="stylesheet" href="<?php echo HTML_PATH_THEME ?>assets/css/main.css">
<!--[if lte IE 9]><link rel="stylesheet" href="<?php echo HTML_PATH_THEME ?>assets/css/ie9.css" /><![endif]-->
<!--[if lte IE 8]><link rel="stylesheet" href="<?php echo HTML_PATH_THEME ?>assets/css/ie8.css" /><![endif]-->
<link rel="stylesheet" href="<?php echo HTML_PATH_THEME ?>assets/css/bludit.css">
<?php
// Add local Fonts Awesome
Theme::fontAwesome();
// Load plugins, hook: Site head
Theme::plugins('siteHead');
?>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/highlight.min.js"></script>

View File

@ -0,0 +1,83 @@
<!-- Show each post on this page -->
<?php foreach ($posts as $Post): ?>
<article class="post">
<!-- Show plugins, Hook: Post Begin -->
<?php Theme::plugins('postBegin') ?>
<!-- Post's header -->
<header>
<div class="title">
<h1><a href="<?php echo $Post->permalink() ?>"><?php echo $Post->title() ?></a></h1>
<p><?php echo $Post->description() ?></p>
</div>
<div class="meta">
<?php
// Get the user who created the post.
$User = $Post->user();
// Default author is the username.
$author = $User->username();
// If the user complete the first name or last name this will be the author.
if( Text::isNotEmpty($User->firstName()) || Text::isNotEmpty($User->lastName()) ) {
$author = $User->firstName().' '.$User->lastName();
}
?>
<time class="published" datetime="2015-11-01"><?php echo $Post->date() ?></time>
<div class="author"><span class="name"><?php echo $author ?></span><img src="<?php echo $User->profilePicture() ?>" alt=""></div>
</div>
</header>
<!-- Cover Image -->
<?php
if($Post->coverImage()) {
echo '<a href="'.$Post->permalink().'" class="image featured"><img src="'.$Post->coverImage().'" alt="Cover Image"></a>';
}
?>
<!-- Post's content, the first part if has pagebrake -->
<?php echo $Post->content(false) ?>
<!-- Post's footer -->
<footer>
<!-- Read more button -->
<?php if($Post->readMore()) { ?>
<ul class="actions">
<li><a href="<?php echo $Post->permalink() ?>" class="button"><?php $Language->p('Read more') ?></a></li>
</ul>
<?php } ?>
<!-- Post's tags -->
<ul class="stats">
<?php
$tags = $Post->tags(true);
foreach($tags as $tagKey=>$tagName) {
echo '<li><a href="'.HTML_PATH_ROOT.$Url->filters('tag').'/'.$tagKey.'">'.$tagName.'</a></li>';
}
?>
</ul>
</footer>
<!-- Plugins Post End -->
<?php Theme::plugins('postEnd') ?>
</article>
<?php endforeach; ?>
<!-- Pagination -->
<ul class="actions pagination">
<?php
if( Paginator::get('showNewer') ) {
echo '<li><a href="'.Paginator::urlPrevPage().'" class="button big previous">'.$Language->get('Prev page').'</a></li>';
}
if( Paginator::get('showOlder') ) {
echo '<li><a href="'.Paginator::urlNextPage().'" class="button big next">'.$Language->get('Next page').'</a></li>';
}
?>
</ul>

View File

@ -0,0 +1,27 @@
<article class="post">
<!-- Plugins Page Begin -->
<?php Theme::plugins('pageBegin') ?>
<!-- Post's header -->
<header>
<div class="title">
<h1><a href="<?php echo $Page->permalink() ?>"><?php echo $Page->title() ?></a></h1>
<p><?php echo $Page->description() ?></p>
</div>
</header>
<!-- Cover Image -->
<?php
if($Page->coverImage()) {
echo '<a href="'.$Page->permalink().'" class="image featured"><img src="'.$Page->coverImage().'" alt="Cover Image"></a>';
}
?>
<!-- Post's content, the first part if has pagebrake -->
<?php echo $Page->content() ?>
<!-- Plugins Page End -->
<?php Theme::plugins('pageEnd') ?>
</article>

View File

@ -0,0 +1,57 @@
<article class="post">
<!-- Show plugins, Hook: Post Begin -->
<?php Theme::plugins('postBegin') ?>
<!-- Post's header -->
<header>
<div class="title">
<h1><a href="<?php echo $Post->permalink() ?>"><?php echo $Post->title() ?></a></h1>
</div>
<div class="meta">
<?php
// Get the user who created the post.
$User = $Post->user();
// Default author is the username.
$author = $User->username();
// If the user complete the first name or last name this will be the author.
if( Text::isNotEmpty($User->firstName()) || Text::isNotEmpty($User->lastName()) ) {
$author = $User->firstName().' '.$User->lastName();
}
?>
<time class="published" datetime="2015-11-01"><?php echo $Post->date() ?></time>
<div class="author"><span class="name"><?php echo $author ?></span><img src="<?php echo $User->profilePicture() ?>" alt=""></div>
</div>
</header>
<!-- Cover Image -->
<?php
if($Post->coverImage()) {
echo '<a href="'.$Post->permalink().'" class="image featured"><img src="'.$Post->coverImage().'" alt="Cover Image"></a>';
}
?>
<!-- Post's content, the first part if has pagebrake -->
<?php echo $Post->content() ?>
<!-- Post's footer -->
<footer>
<!-- Post's tags -->
<ul class="stats">
<?php
$tags = $Post->tags(true);
foreach($tags as $tagKey=>$tagName) {
echo '<li><a href="'.HTML_PATH_ROOT.$Url->filters('tag').'/'.$tagKey.'">'.$tagName.'</a></li>';
}
?>
</ul>
</footer>
<!-- Show plugins, Hook: Post End -->
<?php Theme::plugins('postEnd') ?>
</article>

View File

@ -0,0 +1,41 @@
<!-- Intro -->
<section id="intro">
<header>
<h2><a href="<?php echo $Site->url() ?>"><?php echo $Site->title() ?></a></h2>
<p><?php echo $Site->slogan() ?></p>
</header>
</section>
<?php Theme::plugins('siteSidebar') ?>
<!-- Footer -->
<section id="footer">
<ul class="icons">
<?php
if($Site->twitter()) {
echo '<li><a href="'.$Site->twitter().'" class="fa-twitter"><span class="label">Twitter</span></a></li>';
}
if($Site->facebook()) {
echo '<li><a href="'.$Site->facebook().'" class="fa-facebook"><span class="label">Facebook</span></a></li>';
}
if($Site->instagram()) {
echo '<li><a href="'.$Site->instagram().'" class="fa-instagram"><span class="label">Instagram</span></a></li>';
}
if($Site->github()) {
echo '<li><a href="'.$Site->github().'" class="fa-github"><span class="label">Github</span></a></li>';
}
if( $plugins['all']['pluginRSS']->installed() ) {
echo '<li><a href="'.DOMAIN_BASE.'rss.xml'.'" class="fa-rss"><span class="label">RSS</span></a></li>';
}
if( $plugins['all']['pluginSitemap']->installed() ) {
echo '<li><a href="'.DOMAIN_BASE.'sitemap.xml'.'" class="fa-sitemap"><span class="label">Sitemap</span></a></li>';
}
?>
</ul>
<p class="copyright"><?php echo $Site->footer() ?> | <a href="http://www.bludit.com">BLUDIT</a></p>
</section>

View File

@ -8,6 +8,33 @@ a.home-title {
color: #222;
}
ul, ol {
margin-bottom: 1.5em;
}
ul li {
padding-bottom: 6px;
}
table {
width: 100%;
margin-bottom: 1.5em;
}
table thead {
background: #555555;
color: #FFF;
}
table td,
table th {
padding-left: 5px;
}
h1,
h2 {
font-weight: bold;
}
/* PAGES */
article.page:not(:last-child) {
@ -32,8 +59,17 @@ div.plugin:not(:last-child) {
margin-bottom: 40px;
}
div.plugin h2.plugin-label {
div.plugin > h1,
div.plugin > h2,
div.plugin > h3,
div.plugin > h4,
div.plugin > h5 {
font-size: 1em;
}
div.plugin h2.plugin-label {
border-bottom: 1px solid #ebebeb;
padding-bottom: 5px;
text-transform: uppercase;
margin: 20px 0;
}
@ -43,10 +79,23 @@ div.plugin ul {
padding: 0;
}
/* PLUGIN MENU */
div.plugin-menu li.menu:not(:last-child) {
margin-bottom: 10px;
}
div.plugin-menu ul.submenu {
margin-left: 10px;
}
/* PLUGIN PAGES */
div.plugin-pages li.parent h3 {
margin-bottom: 5px;
margin-top: 10px;
}
div.plugin-pages ul.child {
margin-left: 5px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -11,9 +11,15 @@
<img src="<?php echo $page->coverImage() ?>" alt="<?php echo $page->slug() ?>">
<?php } ?>
</header>
<?php echo $page->content() ?>
<?php echo $page->contentBreak() ?>
<footer>
<div class="category"><i class="icon-price-tag"></i> <?php echo $page->category() ?></div>
<?php if ($page->readMore() ) { ?>
<div class="readmore">
<a href="<?php echo $page->permalink() ?>">
<i class="icon-arrow-down"></i> <?php echo $Language->get('Read more') ?>
</a>
</div>
<?php } ?>
</footer>
</article>
<?php endforeach ?>

View File

@ -57,7 +57,7 @@ define('PATH_ABSTRACT', PATH_KERNEL.'abstract'.DS);
define('CHECK_SYMBOLIC_LINKS', TRUE);
// Filename for posts and pages
define('FILENAME', 'index.md');
define('FILENAME', 'index.txt');
// Domain and protocol
define('DOMAIN', $_SERVER['HTTP_HOST']);
@ -321,7 +321,7 @@ function install($adminPassword, $email, $timezone)
'description'=>$Language->get('About your site or yourself'),
'username'=>'admin',
'tags'=>array(),
'status'=>'published',
'status'=>'fixed',
'date'=>$currentDate,
'dateModified'=>'',
'allowComments'=>true,
@ -342,7 +342,7 @@ function install($adminPassword, $email, $timezone)
'position'=>1,
'coverImage'=>'',
'md5file'=>'',
'category'=>'',
'category'=>'general',
'uuid'=>md5(uniqid())
)
);
@ -367,7 +367,7 @@ function install($adminPassword, $email, $timezone)
'language'=>$Language->getCurrentLocale(),
'locale'=>$Language->getCurrentLocale(),
'timezone'=>$timezone,
'theme'=>'editorial',
'theme'=>'kernel-panic',
'adminTheme'=>'default',
'homepage'=>'',
'itemsPerPage'=>6,
@ -418,10 +418,7 @@ function install($adminPassword, $email, $timezone)
file_put_contents(PATH_DATABASES.'syslog.php', $dataHead.json_encode($data, JSON_PRETTY_PRINT), LOCK_EX);
// File security.php
$randomKey = sha1( uniqid() );
$data = array(
'key1'=>$randomKey,
'minutesBlocked'=>5,
'numberFailuresAllowed'=>10,
'blackList'=>array()
@ -431,8 +428,9 @@ function install($adminPassword, $email, $timezone)
// File categories.php
$data = array(
'videos'=>array('name'=>'Videos', 'list'=>array()),
'music'=>array('name'=>'Music', 'list'=>array())
'general'=>array('name'=>'General', 'list'=>array()),
'music'=>array('name'=>'Music', 'list'=>array()),
'videos'=>array('name'=>'Videos', 'list'=>array())
);
file_put_contents(PATH_DATABASES.'categories.php', $dataHead.json_encode($data, JSON_PRETTY_PRINT), LOCK_EX);
@ -497,11 +495,11 @@ function install($adminPassword, $email, $timezone)
);
// File for error page
$data = 'Title: '.$Language->get('Error').PHP_EOL.'Content: '.$Language->get('The page has not been found');
$data = 'Title: '.$Language->get('Error').PHP_EOL.'Content: '.PHP_EOL.$Language->get('installer-page-error-content');
file_put_contents(PATH_PAGES.'error'.DS.FILENAME, $data, LOCK_EX);
// File for about page
$data = 'Title: '.$Language->get('About').PHP_EOL.'Content: '.$Language->get('the-about-page-is-very-important').' '.$Language->get('change-this-pages-content-on-the-admin-panel');
$data = 'Title: '.$Language->get('About').PHP_EOL.'Content: '.PHP_EOL.$Language->get('installer-page-about-content');
file_put_contents(PATH_PAGES.'about'.DS.FILENAME, $data, LOCK_EX);
// File for welcome page