tam olarak nasıl debug yaparsın bilmiyorum ancak javascript kodlarının tarayıcı uyumluluğuna bakarak safarinin desteklemediği kodları tespit ederek bunları düzenleme yoluna gidebilirsin belki
mantığı aslında belli bir standartta yazmak ve mümkün olduğunca içinde saf php yazmak yerine direktifleri kullanarak ya da özel yapı oluşturarak kullanmak.
yani html kodlarını phpden ayırıyoruz. ayrıca tabi bazı avantajlarıda var örneğin blade engine'de layout sistemi oluşturmak çok kolay ve bunu extend ederek tek bir yerden kontrolünü sağlamak çok rahat.
yapılışı ise aslında tamamen kodları regex ile ayrıştırıp işlemekten ibaret, elbette çok kolay değil, her ihtimali düşünmek gerekiyor.
mesela birlikte bir örnek yapalım, yapacağımız template engine'de sadece değişkenleri ve foreach işlemlerini dönüştürelim.
dolayısı ile php dosyasında değişkeni yazdırırken <?php echo $degisken; ?> yerine {{ degisken }} şeklinde bir kullanım olsun ve foreach için şunun yerine;
<?php foreach($todos as $key => $todo): ?>
<li>
<?=$todo?>
</li>
<?php endforeach; ?>
şöyle bir kullanımımız olsun
@foreach(todos as todo)
<li>{{ todo }}</li>
@endforeach
bu mantıkta ilk olarak temel bir sınıfa ihtiyacımız var. kabaca oluşturduğum ve test ettiğim sınıfı yazayım;
<?php
// template.php
class TemplatEngine {
public $view;
public function view($view, $data = [])
{
extract($data);
$viewName = $view . '.ptemplate.php';
$viewPath = __DIR__ . '/views/' . $viewName;
ob_start();
require $viewPath;
$this->view = ob_get_clean();
$this->parse();
$viewCachePath = __DIR__ . '/cache/' . md5($viewName) . '.cache.php';
// cache yoksa oluştur
if (!file_exists($viewCachePath)) {
file_put_contents($viewCachePath, $this->view);
}
if (filemtime($viewCachePath) < filemtime($viewPath)) {
file_put_contents($viewCachePath, $this->view);
}
require $viewCachePath;
}
public function parse()
{
$this->parseVariables();
$this->parseForeach();
}
public function parseVariables()
{
$this->view = preg_replace_callback('/{{(.*?)}}/', function($variable) {
return '<?=$' . trim($variable[1]) . '?>';
}, $this->view);
}
public function parseForeach()
{
$this->view = preg_replace_callback('/@foreach\((.*?) as (.*?)\)/', function($variable) {
if (strstr($variable[2], '=>')) {
[$key, $value] = explode('=>', $variable[2]);
return '<?php foreach($' . trim($variable[1]) . ' as $' . trim($key) . ' => $' . trim($value) . '): ?>';
}
return '<?php foreach($' . trim($variable[1]) . ' as $' . $variable[2] . '): ?>';
}, $this->view);
$this->view = preg_replace_callback('/@endforeach/', function($a){
return '<?php endforeach; ?>';
}, $this->view);
}
}
ve klasör yapın şöyle olsun
cache/
views/
template.php
index.php
index.php de dosyalarımız;
<?php
require __DIR__ . '/template.php';
$template = new PrototurkTemplateEngine();
$template->view('index', [
'title' => 'Prototürk',
'name' => 'Tayfun Erbilen',
'todos' => [
'todo 1',
'todo 2',
'todo 3'
]
]);
views altında index.ptemplate.php adında bir dosyamız olacak ve içinde şunlar yazacak;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
</head>
<body>
<h1>Hoşgeldin, {{ name }}</h1>
<ul>
@foreach(todos as todo)
<li>
{{ todo }}
</li>
@endforeach
</ul>
<ul>
@foreach(todos as key => todo)
<li>
{{ todo }}
</li>
@endforeach
</ul>
</body>
</html>
sonuç olarak cache/ klasöründe şöyle bir çıktı göreceksin;
// c9309029e1762f7da2afa048543c13b2.cache.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?=$title?></title>
</head>
<body>
<h1>Hoşgeldin, <?=$name?></h1>
<ul>
<?php foreach($todos as $todo): ?>
<li>
<?=$todo?>
</li>
<?php endforeach; ?>
</ul>
<ul>
<?php foreach($todos as $key => $todo): ?>
<li>
<?=$todo?>
</li>
<?php endforeach; ?>
</ul>
</body>
</html>
tabi temelde bu çok basit bir örneğiydi, blade engine'deki gibi extend section push gibi direktiflerle çok daha kullanışlı hale getirilebilir.
eğer mesajları gruplamadan böyle bir şey yapmak istersen html yapını şöyle düşünelim;
<div class="chat">
<div class="message me">
test message
<img src="https://gravatar.com/avatar/be2da7976e64ff4211a4ff7b22b10b58?d=https%3A%2F%2Fassets.codepen.io%2Finternal%2Favatars%2Fusers%2Fdefault.png&fit=crop&format=auto&height=80&version=0&width=80" alt="">
</div>
<div class="message me">
test message
<img src="https://gravatar.com/avatar/be2da7976e64ff4211a4ff7b22b10b58?d=https%3A%2F%2Fassets.codepen.io%2Finternal%2Favatars%2Fusers%2Fdefault.png&fit=crop&format=auto&height=80&version=0&width=80" alt="">
</div>
<div class="message me">
test message
<img src="https://gravatar.com/avatar/be2da7976e64ff4211a4ff7b22b10b58?d=https%3A%2F%2Fassets.codepen.io%2Finternal%2Favatars%2Fusers%2Fdefault.png&fit=crop&format=auto&height=80&version=0&width=80" alt="">
</div>
<div class="message">
test message
<img src="https://gravatar.com/avatar/be2da7976e64ff4211a4ff7b22b10b58?d=https%3A%2F%2Fassets.codepen.io%2Finternal%2Favatars%2Fusers%2Fdefault.png&fit=crop&format=auto&height=80&version=0&width=80" alt="">
</div>
<div class="message">
test message
<img src="https://gravatar.com/avatar/be2da7976e64ff4211a4ff7b22b10b58?d=https%3A%2F%2Fassets.codepen.io%2Finternal%2Favatars%2Fusers%2Fdefault.png&fit=crop&format=auto&height=80&version=0&width=80" alt="">
</div>
<div class="message me">
test message
<img src="https://gravatar.com/avatar/be2da7976e64ff4211a4ff7b22b10b58?d=https%3A%2F%2Fassets.codepen.io%2Finternal%2Favatars%2Fusers%2Fdefault.png&fit=crop&format=auto&height=80&version=0&width=80" alt="">
</div>
<div class="message">
test message
<img src="https://gravatar.com/avatar/be2da7976e64ff4211a4ff7b22b10b58?d=https%3A%2F%2Fassets.codepen.io%2Finternal%2Favatars%2Fusers%2Fdefault.png&fit=crop&format=auto&height=80&version=0&width=80" alt="">
</div>
<div class="message">
test message
<img src="https://gravatar.com/avatar/be2da7976e64ff4211a4ff7b22b10b58?d=https%3A%2F%2Fassets.codepen.io%2Finternal%2Favatars%2Fusers%2Fdefault.png&fit=crop&format=auto&height=80&version=0&width=80" alt="">
</div>
</div>
<div class="add-chat">
<input type="text" placeholder="Yeni mesaj ekle">
<label>
<input type="checkbox" value="1" name="me">
kendin olarak gönder
</label>
</div>
ufak bir css
.chat {
border: 1px solid #ddd;
padding: 15px;
}
.message {
padding: 10px;
background: #eee;
border-radius: 10px;
margin-bottom: 5px;
}
.message img {
display: none;
}
.message.me {
background: lime;
}
ve jquery tarafın şöyle olabilir
function setImages() {
$('.message img').hide();
$('.message.me + .message:not(.me)').prev('.message.me').find('img').show();
$('.message:not(.me) + .message.me').prev('.message:not(.me)').find('img').show();
$('.message:last').find('img').show();
}
setImages();
$('.add-chat input').on('keyup', function(e) {
if (e.key === 'Enter') {
$('.chat').append(`<div class="message${$(this).closest('.add-chat').find('input[type="checkbox"]').is(':checked') ? ' me' : ''}">
${$(this).val()}
<img src="https://gravatar.com/avatar/be2da7976e64ff4211a4ff7b22b10b58?d=https%3A%2F%2Fassets.codepen.io%2Finternal%2Favatars%2Fusers%2Fdefault.png&fit=crop&format=auto&height=80&version=0&width=80" alt="">
</div>`);
$(this).val('');
setImages();
}
});
demoyu görmek istersen: https://codepen.io/tayfunerbilen/pen/BaWGodP
sadece css ile yapmak istersen;
<ul>
<li tabindex="0">
Ders 1
<ul>
<li tabindex="0">
Ünite 1
<ul>
<li tabindex="0">
Konu 1
<ul>
<li tabindex="0">Kazanım 1</li>
<li tabindex="0">Kazanım 2</li>
<li tabindex="0">Kazanım 3</li>
<li tabindex="0">Kazanım 4</li>
</ul>
</li>
<li tabindex="0">Konu 2</li>
<li tabindex="0">Konu 3</li>
</ul>
</li>
<li tabindex="0">Ünite 2</li>
<li tabindex="0">Ünite 3</li>
</ul>
</li>
<li tabindex="0">Ders 2</li>
<li tabindex="0">Ders 3</li>
</ul>
<style>
li ul {
display: none;
}
li:focus-within > ul {
display: block;
}
</style>
bu yaklaşım bana çok doğru gelmiyor. her işlem için ajax çalıştırmak yerine bu kontrolleri client-side kontrol etmek çok daha mantıklı.
nasıl yapabilirim dersen zamanında çektiğim 2 video var, bunlardan birisi mutlaka bu işini çözecektir, incelemeni öneririm:
https://www.youtube.com/watch?v=Q4BS0vzU13g
https://www.youtube.com/watch?v=q9cV7Rfrlqc
bana pek mantıklı gelmedi bu şekilde değişkende tutmak yerine bir array ile basitçe dönülebilirdi. Ama bu yapıda şöyle bir şey kullanılabilir;
<?php
function getUsers($project) {
$users = [];
for ( $i = 1; $i <= 4; $i++ ){
if (isset($project['kisi' . $i]) && !empty($project['kisi' . $i])) {
$users[] = $project['kisi' . $i];
}
}
return implode(', ', $users);
}
?>
<div>
<?= $proje[$i]["p_adi"]; ?>
<?=getUsers($proje[$i])?>
</div>
basit bir tarih kontrolü aslında, örneğin;
function logo () {
$date = date('m-d');
switch( $date ) {
case '04-23':
return '23nisanlogo.png';
break;
case '05-19':
return '19mayislogo.png';
break;
default:
return 'logo.png';
break;
}
}
echo '<img src="' . logo() . '" />'
users[say] = row.id + " numaralı " + row.kadi + " adlı kullanıcı veritanında var"; yerine şöyle bir şey yapabilirsin
const sqlite3 = require("sqlite3").verbose();
var uyeler = new sqlite3.Database("db/uyeler.sqlite");
const users = [];
uyeler.each("SELECT * FROM user",function (err,row) {
users.push(row);
});
console.log(users);
teşekkürler berkay, gerekli düzenlemeleri yapıyorum yakında bir moderatör sistemi getireceğim ve güvenilir prototürk üyelerinin bazılarına moderatör yetkisi vereceğim en azından ben yokken bu gibi sorulara müdehale edebiliriz birlikte hızlıca.
arkadaşlar ne yazık ki böyle insanlar hep olacak, bir moderasyon sistemi hazırlıyorum güvenilir prototürk üyelerinin bazılarını moderatör yaparak bu gibi konulara daha hızlı müdehale etmeye çalışacağız, ben her zaman online olamıyorum en azından içimizden birileri hızlıca görüp bir çözüm üretebilir, kusura bakmayın bu eşek herifler adına ben özür diliyorum :)