Merhaba. Dosya yapınızı bilmiyorum. Sayfaların uzantısı .php mi yoksa .html mi? Sayfa yönlendirmeleri nasıl yapılmış? Projeyi görmeden net cevap vermek zor.
Varsayımsal bir örnek üzerinden gidelim. Diyelim ki kök klasörünüzde şöyle bir dosyalama yapılmış:
- index.php (anasayfanız)
- hakkimizda.php
- iletisim.php
- template klasöründe: head.php, foot.php
- styles klasöründe: anasayfa.css, hakkimizda.css, iletisim.css
- scripts klasöründe: jquery.min.js, anasayfa.js, hakkimizda.js, iletisim.js
Tüm sayfalarda sabit title kullanıldığına göre tahmin ediyorum ki tüm sitenin tüm sayfaları şöyle kurgulanmış:
Örneğin hakkimizda.php:<?php include("template/head.php"); ?> <link rel="stylesheet" href="styles/hakkimizda.css" /> <h1>Hakkımızda Sayfası</h1> <p>Hakkımızda sayfasının içeriği</p> <script src="scripts/jquery.min.js"></script> <script src="scripts/hakkimizda.js"></script> <?php include("template/foot.php"); ?>
Yani her sayfa önce head.php dosyasını include ediyor. Sonra kendi içeriğini bulunduruyor. Sonra da foot.php dosyasını include ediyor.
Haliyle aynı head.php dosyası her sayfada aynı şekilde göründüğünden,<title></title>
da her sayfada aynı oluyor.
template/head.php:<html> <head> <title>Site Başlığı</title> </head> <body> <section id="contentPlaceHolder">
template/foot.php:
</section> </body> </html>
Tabi bu sıralamada hakkimizda.php dosyasının içeriği head.php dosyasının içeriğinden sonra geldiği için hakkimizda.php dosyasında oluşturacağınız bir değişkenle head.php dosyasına etki edemiyorsunuz.
Bu sorunu aşmak için kök dizininizde controller adında bir klasör oluşturun ve içine sayfalarınızla aynı isimde php dosyaları oluşturun: - controller
- anasayfa.php (index.php'nin controller'ı)
- hakkimizda.php
- iletisim.php
Ve hakkimizda.php sayfanızın içeriğini şu şekilde güncelleyin:
<?php include("controller/hakkimizda.php"); ?>
<?php include("template/head.php"); ?>
<link rel="stylesheet" href="styles/hakkimizda.css" />
<h1>Hakkımızda Sayfası</h1>
<p>Hakkımızda sayfasının içeriği</p>
<script src="scripts/jquery.min.js"></script>
<script src="scripts/hakkimizda.js"></script>
<?php include("template/foot.php"); ?>
Sayfanızın başına controller/hakkimizda.php dosyasını include etmiş oldunuz. Bu controller dosyası sayfanın en başında çağırıldığı için burada oluşturacağınız değişkenleri template/head.php dosyanızdan da okuyabileceksiniz. Mesela controller'ınızın içine şunları yazın:
controller/hakkimizda.php
<?php
$pageTitle = "Hakkımızda Sayfası";
Sonra da template/head.php dosyanızdaki <title>
alanını güncelleyin:
<html>
<head>
<title><?=(isset($pageTitle) ? $pageTitle : "Site Başlığı")?></title>
</head>
<body>
<section id="contentPlaceHolder">
Yani demiş oldunuz ki: Eğer $pageTitle
adında bir değişken varsa buraya onu yaz. Yoksa "Site Başlığı" yaz.
Merhaba. Bahsettiğiniz olay bir CSS animation olayı. Sitedekinin aynısını alıp buraya eklemek hoş olmaz.
Diyelim ki şöyle bir yapınız var:
<nav>
<a><i class="icon">ikon</i> Link 1</a>
<a><i class="icon">ikon</i> Link 2</a>
<a><i class="icon">ikon</i> Link 3</a>
<a><i class="icon">ikon</i> Link 4</a>
</nav>
Stil olarak şu yapıyı kullanabilirsiniz:
nav.menu a {
display:flex;
flex-direction:row;
align-items:center;
justify-content:flex-start;
}
nav.menu a:hover .icon {
animation: .5s cubic-bezier(0.35, 0.10, 0.20, 0.95) both salla;
transform-origin: top right;
}
@keyframes salla {
0%,to { transform: rotate(0) }
15% { transform: rotate(8deg) }
30% { transform: rotate(-8deg) }
45% { transform: rotate(6deg) }
56% { transform: rotate(-6deg) }
70% { transform: rotate(3deg) }
85% { transform: rotate(-3deg) }
95% { transform: rotate(2deg) }
}
Sitede aşağı yukarı buna benzer bir işlem yapılmış.
Evet, "veritabanı kullanmadan veritabanındaki veriyi hızlı bir şekilde çekip listelemenin" bir yolu var: Cache'lemek.
- Listeleme yapacağınız sayfaya girildiğinde bir kontrol yapmalısınız: Bu liste cache'lenmiş bir json dosyasında mevcut mu?
- Liste henüz cache'lenmemişse veritabanına bağlanıp büyük veriyi çekeceksiniz ve bir json dosyasına yazıp kaydedeceksiniz.
- Liste cache'lenmişse veritabanına hiç bağlanmayıp doğrudan json dosyasını döndüreceksiniz.
Sayfaya ilk giren talihsiz kişi veritabanına bağlanılıp cache'lenmesini sağlayacağı için biraz bekleyecek. Ama sonraki kişiler veriyi doğrudan json dosyasından alacakları için daha hızlı sonuç alacaklar.
Tabi burada önemli noktayı kaçırmamak lazım: - Veritabanından anlık olarak doğru veri okumanız gerekiyorsa bu yöntemi kullanamazsınız. Çünkü herkes son cache'lediğiniz veriyi görür.
- Verinin ne zaman cache'leneceğini ayarlamalısınız. Mesela son cache'lemenizin üstünden 2 saat geçmişse yeniden cache'lemeniz gerekiyor olabilir. Veya cache'lemeyi tamamen ayrı bir sayfadan sağlayabilirsiniz. Mesela yönetim panelinden bu veritabanı tablosunu etkileyecek bir değişim yapıldığında yeniden cache'leme yapılmasını sağlayabilirsiniz. Veya tüm değişiklikler yapıldıktan sonra bir "Cache'le" butonuna basılmasıyla birlikte bu işlemi yaptırabilirsiniz. İşin algoritması, verinin değişim sıklığına veya canlı verinin görüntülenme mecburiyetine göre değişir.
Bu cache'leme işlemini daha da üst seviyeye taşıyıp bütün bir sayfayı cache'leyebilirsiniz. Mesela "Yeni Ürünler" sayfasına ilk girişte PHP ile bu sayfayı oluşturduktan sonra çıktıyı bir html dosyası olarak kaydedersiniz ve eğer böyle bir html dosyası varsa doğrduan bu dosyanın görüntülenmesini istersiniz. Böylece sayfa her istekte yeniden render edilmemiş olur.
Sözün özü, cache'leme mekanizmalarını araştırmalısınız. Eğer bir framework kullanıyorsanız (Codeigniter, Laravel... gibi) bu tip mekanizmalar zaten framework içinde mevcuttur ama birkaç düzenlemeyle aktive edilmesi gerekir.
Merhaba. Bu sayfadayken firebug console'u açıp aşağıdaki kodları yapıştırırsanız sizinkine benzer bir test ortamını bu sayfada oluşturabilirsiniz:
$("body").prepend(`<div id="test"></div>`);
const $test = $("body > #test");
$test.append(`
<style>
#test { display:flex; flex-direction:row; align-items:flex-start; justify-content:space-evenly; width:100vw; padding:0 10px; }
#test > div { display:flex; flex-direction:column; align-items:center; justify-content:flex-start; flex:1; margin:10px; }
#test > div > button.fa-edit { margin:5px; padding:10px; border:none; background:#ccc; color:#000; width:100%; cursor:pointer; }
#test > div > div { width:100%; display:flex; flex-direction:column; padding:5px 0; }
#test > div > div > input.submit-form__input { border:1px solid #ccc; background:#fff; padding:10px 0; text-indent:10px; margin:5px 0; }
</style>
`);
$test.append(`<div><button class="fa fa-edit">Buton A</button></div>`);
$test.append(`<div><button class="fa fa-edit">Buton B</button></div>`);
$test.append(`<div><button class="fa fa-edit">Buton C</button></div>`);
$buttons = $test.find("> div > button.fa-edit");
$buttons.on("click", function() {
$(this).next("div").remove();
$(this).after("<div></div>");
$inputContainer = $(this).next("div");
$inputContainer.append(`<input type="text" class="submit-form__input" value="${$(this).text().replace("Buton","Değer")} 1" />`);
$inputContainer.append(`<input type="text" class="submit-form__input" value="${$(this).text().replace("Buton","Değer")} 2" />`);
$inputContainer.append(`<input type="text" class="submit-form__input" value="${$(this).text().replace("Buton","Değer")} 3" />`);
$inputContainer.append(`<input type="text" class="submit-form__input" value="${$(this).text().replace("Buton","Değer")} 4" />`);
});
Kodu çalıştırdığınızda sayfanın üstünde sizinkiyle aynı class'a sahip 3 buton belirecek ve butonlara tıklandığında da sizinkilerle aynı class'lara sahip 4 input oluşacak.
Sizdeki kodları böylece simule ettikten sonra sizin yazdığınız kodu async/await olmadan yazıp çalıştırdım:
const butonlar = document.getElementsByClassName('fa-edit');
function degistir() {
for (buton of butonlar) {
buton.click();
let inputlar = document.getElementsByClassName('submit-form__input');
inputlar[1].value = 'deneme';
}
}
degistir();
Sonuç olarak bütün butonlara basıldı ve input'lar oluştu ama sizde de olduğu gibi 2.input'a "deneme" yazmadı. Aynen sizin de düşündüğünüz gibi bir durum var. Aslında kodunuz doğru ama butona tıklandığında input'lar oluşturulması henüz tamamlanmadığı için input'u bulup değişiklik yapamıyordu.
Sonra sizin denediğiniz gibi async/await ile denedim:
const butonlar = document.getElementsByClassName('fa-edit');
async function degistir() {
for (buton of butonlar) {
await buton.click();
let inputlar = document.getElementsByClassName('submit-form__input');
inputlar[1].value = 'deneme';
}
}
degistir();
Böyle yapınca da tıpkı sizdeki gibi bir Promise
döndü. Bu normal. Oluşturduğunuz fonksiyon async
olduğu için Promise
dönüyor. Promise sonucunu elde etmek için fonksiyonu çağırırken await
kullanmalısınız. Böylece fonksiyonunuz içindeki await
sonucu tamamlanmadan (butonlara tıklanma olayının işlemleri bitmeden) sonraki işlemlere geçmeyecektir.
Cevabı lüzumsuzca uzattıktan sonra :D aslında tek satırda verebileceğim cevap şu:
await degistir();
olarak deneyin.
PHP ile yapmanız mümkün.
stackoverflow.com'da şöyle bir başlık var:
url'den gelen bir görseli nasıl boyutlandırabilirim ve küçük boyutlu bir görsel yapabilirim?
Gelen cevapta şöyle söylenmiş:
PHP'nin imagecopyresamled işlevini kullanabilirsiniz. php.net'ten basit bir örnek:
<?php
// Dosya ve yeni boyut oranı
$dosya = 'https://www.gravatar.com/avatar/81b67dbba3bd3f9317db992d098d3fc0?s=80&d=mp&r=g';
$oran = 0.5;
// İçerik türü
header('Content-type: image/jpeg');
// Yeni resmin boyutları
list($genislik, $yukseklik) = getimagesize($dosya);
$yeniGenislik = $genislik * $oran;
$yeniYukseklik = $yukseklik * $oran;
// Görüntüleri yükleyelim
$hedef = imagecreatetruecolor($yeniGenislik, $yeniYukseklik);
$kaynak = imagecreatefromjpeg($dosya);
// Görüntüyü örnekleyelim
imagecopyresampled($hedef, $kaynak, 0, 0, 0, 0, $yeniGenislik, $yeniYukseklik, $genislik, $yukseklik);
// Görüntüyü çıktılayalım
imagejpeg($hedef, null, 100);
?>
Yani PHP tarafında API üzerinden aldığınız görselleri bu yöntemle yeniden boyutlandırabiliyorsunuz. Tabi burada tek bir görselin çıktısı basılmış ve bu php dosyasının jpeg dosyası gibi davranması için header
atanmış.
Bu sayfaya url verisini GET parametresi olarak iletirseniz size görseliin %50 küçültülmüş halini jpeg formatında dönecektir. Yani kodları şöyle düzenleyebiliriz:
kucult.php
<?php
if(!isset($_GET["url"])) exit();
// Dosya ve yeni boyut oranı
$dosya = $_GET["url"];
$oran = 0.5;
// İçerik türü
header('Content-type: image/jpeg');
// Yeni resmin boyutları
list($genislik, $yukseklik) = getimagesize($dosya);
$yeniGenislik = $genislik * $oran;
$yeniYukseklik = $yukseklik * $oran;
// Görüntüleri yükleyelim
$hedef = imagecreatetruecolor($yeniGenislik, $yeniYukseklik);
$kaynak = imagecreatefromjpeg($dosya);
// Görüntüyü örnekleyelim
imagecopyresampled($hedef, $kaynak, 0, 0, 0, 0, $yeniGenislik, $yeniYukseklik, $genislik, $yukseklik);
// Görüntüyü çıktılayalım
imagejpeg($hedef, null, 100);
?>
Böylece bize, url'si verilen bir görseli %50 küçülten kendimize ait bir url'miz var.
Diyelim ki siz görsellerinizi şu şekilde gösteriyordunuz:
<img src="https://www.gravatar.com/avatar/81b67dbba3bd3f9317db992d098d3fc0?s=80&d=mp&r=g" />
<img src="https://www.gravatar.com/avatar/150c62d1d24332b2d2d39ac57ae902a0?s=80&d=mp&r=g" />
Artık böyle göstermesiniz:
<img src="kucult.php?url=https://www.gravatar.com/avatar/81b67dbba3bd3f9317db992d098d3fc0?s=80&d=mp&r=g" />
<img src="kucult.php?url=https://www.gravatar.com/avatar/150c62d1d24332b2d2d39ac57ae902a0?s=80&d=mp&r=g" />
Yani görselinizin url'sini, kucult.php sayfanıza url key'i ile get parametresi olarak göndermelisiniz.
Bu yöntem çok da kullanışlı olmayacaktır. Çok sayıda görsel için PHP'yi (yani sunucuyu) her seferinde yormuş olacaksınız.
Eğer bu görsellerin boyutlandırılmış hallerini sunucunuza kaydetme imkânınız varsa daha performanslı bir işlem yapmış olursunuz.
Aslında bu işi front-end tarafında çözmeniz çok daha verimli olacaktır. Görsellere bir lazyload işlemi uygulamalısınız. Görsel ekranda görünmüyorsa html'inizden (DOM'dan) kalkmalı ve böylece tarayıcı o görseli konumlandırmakla uğraşmamalı. Front-end tarafında hangi teknolojiyi (JQuery, React, Vue, Svelte, Angular...) kullandığınızı bilemiyorum ama hepsinde bir lazyload modülü/plugin'i bulabilirsiniz.
JQuery için lazyload örneği olarak Google'da arama yaptığımda karşıma şöyle bir örnek çıktı:
JQuery ile Lazy Load Kullanarak Image Yükleme
Kodunuz localhost'ta çalışıp uzak sunucuda çalışmıyorsa aklıma gelen 3-4 ihtimal var:
- Kodunuzda localhost'ta çalışmaya uygun yollar/değerler bulunuyordur. Mesela veritabanı şifresi, .htaccess dosyasında belirtilen yollar, include yolları...
- Sunucuda oluşturduğunuz veritabanına bağlandığınız kullanıcı adına, veritabanına yazma yetkisi verilmemiş olabilir.
- Excel dosyasının boyutu çok büyükse ve sunucuda belirlenmiş maksimum upload sınırını aşıyorsa hataya düşüyor olabilirsiniz.
- Sunucudaki PHP ayarlarıyla sizin PHP ayarlarınız farklıdır. Sunucudaki PHP versiyonunu değiştirmeniz veya sunucudaki bazı PHP özelliklerini aktif etmeniz gerekiyor olabilir.
Paylaşımlı sunucular genelde PHP'nin hata gösterme özelliğini kapalı tutarlar. Eğer sunucya attığınızda boş beyaz sayfa görüyorsanız veya istediğiniz bir PHP değerinin olması gereken yerde sadece boşluk varsa muhtemelen orada bir hata vardır ama sunucu bunu göstermiyordur. Hatayı anlamak için bu ayarı açmanız gerekir.
Bir ihtimal de sunucuda hata oluştuğunda kök dizininizde otomatik olarak hataları belirten dosya oluşturuluyor olabilir. FTP'den error_logs.txt, error.log vb bir dosya oluşturulmuş mu diye bakıp oluşan hataları oradan inceleyebilirsiniz.
Hatayı bilmeden yorum yapmak zor.
Merhaba. stackoverflow'da sizinkine benzer bir soru sorulmuş:
Çıktısı link olan JQuery autocomplete
Otomatik tamamlama için, çıktıları link olan (Facebook veya Quora'daki gibi) bir otomatik tamamlama kutusu oluşturmaya çalışıyorum. Basitçe, otomatik tamamlama sonuçları listesinin açılmasını ve insanlar tıkladığında başka sayfalara gitmelerini istiyorum.
Doğru cevap olarak kabul edilen cevapta şöyle yazılmış:
Kolayca yapılabilir. source
kısmını aşağıdaki gibi bir objeler dizisiyle değiştirin:
Yönlendirme yapmak için de select
fonksiyonu kullanın:
$("#term").autocomplete({
source: [
{ value: "www.foo.com", label: "Spencer Kline" },
{ value: "www.example.com", label: "James Bond" },
//...
],
select: function( event, ui ) {
window.location.href = ui.item.value;
}
});
Test etmedim ama örnek olarak inceleyip kendinize uyarlayabilirsiniz.
Bu cevap altında da şöyle bir alt mesajlaşma yapılmış:
- Spencer: JQuery'de yeniyim. Yönlendirme işlemini kodda nereye yerleştireyim?
- karim79: Bir fiddle ekledim. Daha açıklayıcı olur.
- Spencer: Teşekkür ederim. Gerçekten minnettarım. Ama o kadar acemiyim ki yapamıyorum. JQuery öğelerini
<head>
içine, html öğelerini<body>
içine yerleştiriyorum. Yapmam gereken başka bi'şey var mı? - Spencer: Ayrıca, bu kod benim localhost'umda da link vermeme izin verecek mi?
- karim79: Evet verecek. Test sitenizin link'i var mı? Bu kodları nasıl çalıştıracağınızı kendi başınıza öğrenmenizi tavsiye ederim (yani zor yoldan :)) Ayrıca, JQuery UI'nin autocomplete'inden bahsediyoruz değil mi? (Spencer bu soruya cevap vermemiş)
- Henry: Tam aradığım şey!
source
yi değiştirmedim veselect
i şu şekilde değiştirdim:window.location.href = "/search.php?keyword="+ui.item.value;
- Henry: Hatta sayfaya autocomplete kullanarak mı gelinmiş diye anlamak için de url'nin sonuna da suggest key'i ekledim:
?keyword="+ui.item.value+"&suggest="+ui.item.index
. Belki ilerde sunucu log'larında suggest ile arama yapılabilir.
Öncelikle kafa karışıklığını önlemek için js dizisine aktaracağınız php değişkenini farklı bir yerde hazırlamanızı öneririm.
<?php
// js dizisine aktarılacak verileri tutacak bir php dizisi oluşturuyoruz:
$autocompleteArray = [];
// Bu php dizisine tek tek değerleri aktarıyoruz:
foreach($blogcek as $key=>$value) $autocompleteArray[] = '"'.$value['urun_baslik'].'"';
// Dizide toplanan tüm değerleri "," karakteriyle birleştirip bir string elde ediyoruz:
$autocompleteArrayString = implode(",", $autocompleteArray);
?>
<script>
var veriler = [<?=$autocompleteArrayString?>];
</script>
Merhaba. Diyelim ki sayfa.php dosyasında navbar.php dosyasını include
ediyorsunuz. Bu durumda sayfa.php sayfasında bir değişken oluşturursunuz ve navbar.php sayfasında bu değişkenin varlığını kontrol edersiniz. Şöyle ki:
sayfa.php
<?php
define("CONTROL", true); // CONTROL adında bir sabit değişken oluşturduk.
?>
<html>
<head>
<title>Sayfa</title>
</head>
<body>
<?php include("navbar.php"); ?>
<div>Sayfa içeriği</div>
</body>
</html>
Şimdi de navbar.php sayfanızın başında, CONTROL
adlı bir değişkenin oluşturulup oluşturulmadığını kontrol edebiliriz.
navbar.php
<?php if(!isset(CONTROL)) { echo "Bu sayfaya doğrudan erişemezsiniz!"; exit(); ?>
<nav>
navbar içeriğim
</nav>
Bu şekilde, navbar.php dosyasının sadece CONTROL
adlı bir sabit değişken oluşturulmuş sayfalardan erişilebilmesini sağlamış olursunuz.
Bu yöntem PHP'nin Codeigniter framework'ünde kullanılıyor. Muhtemelen diğer framework'lerde de kullanılıyordur.
Infinite scroll, hangi front-end javascript teknolojisini kullandığınıza göre farklı şekillerde yapılabilir. React, Vue veya Svelte kullanıyorsanız yeniden oluşturmanıza gerek kalmadan bunlara uygun bileşenler kullanabilirsiniz.
Diyelim ki JQuery kullanıyorsunuz. O zaman kendi yolunuzu kendiniz geliştirmelisiniz. Örnek olarak şöyle bir kod yazalım:
index.html
<html>
<head>
<title>Infinite Scroll</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<div id="content">
<div class="page" style="background-color:red;">Sayfa 1</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="index.js"></script>
</body>
</html>
Örnek bir sayfa oluşturduk. Bu sayfaya index.css ve index.js dosyalarını da dahil ettik. Ayrıca CDN üzerinden jquery
de çağırdık.
Bir adet div#content
elementimizin içine bir adet div.page
elementi ekledik ve içine de Sayfa 1 yazdık.
Sonradan div#content
elementine eklenecek sayfalarla karışmasın diye div.page
elementine kırmızı bir arkaplan verdik. Buraya eklenecek diğer sayfalara da farklı arkaplan renkleri vereceğiz ve böylece sayfa geçişlerini görebilmiş olacağız.
index.css
* { margin: 0; padding:0; box-sizing: border-box; }
html, body { width:100vw; height:100vh; }
#content { width: 100vw; height: 100vh; overflow-y: scroll; }
#content .page { width: 100vw; height: 150vh; display: flex; align-items: center; justify-content:center; font-size:72px; }
html
ve body
elementlerinin ekranın tamamını kaplamasını sağladık.
div#content
elementimizin de aynı şekilde ekranın tamamını kaplamasını sağladık ve Y yönünde scroll özelliği olmasını istedik.
div.page
elementimize de ekranın %150'si kadar yükseklik verdik ve içindeki yazıyı ortaladık. HTML içinde inline olarak da zaten kırmızı renk vermiştik.
Şimdi amacımız, div#content
elementinde scroll olayı gerçekleştiğinde bu olayı dinlemek ve scroll eğer sayfanın sonuna gelmişse otomatik olarak yeni bir sayfa eklemek...
index.js
var bgColors = ["green","blue","yellow","red"];
var $content = $("#content");
$content.on("scroll", function(e) {
var contentScrollTop = $content.scrollTop() + $content.height();
var pageCount = $content.find(".page").length;
var contentHeight = $content.find(".page").height() * pageCount;
if(contentScrollTop - contentHeight < 100) {
$content.append("<div class='page' style='background-color:"+bgColors[pageCount%4]+"'>Sayfa "+pageCount+"</div>");
}
});
Kodları test edemedim ama aşağı yukarı böyle bir algoritma kullanabilirsiniz...
DÜZELTME
Yukarıdaki javascript kodlarında var $content = $(".content");
yazmışım.
var $content = $("#content");
olarak düzelttim.
O an hangi sayfayı görüntülediğimizin URL'ye yazılması konusu biraz daha detaylı bir konu. O an hangi sayfanın görüntülendiğini tespit edecek hesaplamalar yapmak veya inview
gibi JQuery eklentileri kullanmak mümkün. Bu sorunun kapsamı dışında olduğu için bu konuya girmiyorum. Inview kullanımını araştırabilirsiniz.