$to = 'nobody@example.com';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: webmaster@example.com' . "\r\n" . // ЛЮБОЙ АДРЕС!!!
'Reply-To: webmaster@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
Можно ли сэкономить на загрузке если на сервере средствами php сгенерить календарь, например, только на один конкретный месяц?
очень лёгкого календаря
//==
//== Calendar
//== ======================================= ==//
(function () {
const baseClass = 'calendar';
const directions = {
prev: { cls: 'prev', icon: 'arrow-left' },
next: { cls: 'next', icon: 'arrow-right' },
};
const weekDays = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'];
const months = [
'Январь',
'Февраль',
'Март',
'Апрель',
'Май',
'Июнь',
'Июль',
'Август',
'Сентябрь',
'Октябрь',
'Ноябрь',
'Декабрь',
];
class Calendar {
/**
* @param {HTMLElement} el
* @param {Array} events
*/
constructor(el, events) {
this.data = {
monthName: 'default',
};
this.events = events;
/** @var {HTMLElement} */
this.el = el;
/** @var {HTMLElement} */
this.elDays = null;
/** @var {Date} */
this.today = new Date();
this.updateStartDate(this.today.getFullYear(), this.today.getMonth());
this.el.appendChild(this.makeHeader());
this.el.appendChild(this.makeWeekDays());
this.el.appendChild(this.makeMonthDays());
this.displayYear = this.today.getFullYear();
this.displayMonthIndex = this.today.getMonth();
this.displayMonth = months[this.displayMonthIndex] + ' ' + this.displayYear;
this.el.addEventListener('mouseover', event => {
let handler = event.target.closest('.events');
if (handler) {
let content = handler.querySelector('.popper');
if (content) {
tippy(handler, {
content: `<div class="popper">${content.innerHTML}</div>`,
arrow: true,
arrowType: 'round', // sharp, round
interactive: true,
// trigger:'click'
});
}
}
});
}
updateStartDate(fullYear, monthIndex){
this.firstDayDate = new Date(fullYear, monthIndex, 1);
this.firstDayOfMonth = this.firstDayDate.getDay();
if (!this.firstDayOfMonth) this.firstDayOfMonth = 7;
this.startDate = new Date(
this.firstDayDate.getFullYear(),
this.firstDayDate.getMonth(),
this.firstDayDate.getDate() - this.firstDayOfMonth + 1,
);
}
get displayMonth() { return this.data.monthName; }
set displayMonth(val) {
this.data.monthName = val;
this.elTitle.innerHTML = val;
}
makeHeader() {
const el = document.createElement('div');
const btnPrev = this.makeNavButton('prev');
const btnNext = this.makeNavButton('next');
el.classList.add(`${baseClass}__header`);
el.appendChild(btnPrev);
el.appendChild(this.makeMonthTitle());
el.appendChild(btnNext);
btnPrev.addEventListener('click', event => {
if (this.displayMonthIndex - 1 >= 0) {
this.displayMonthIndex--;
} else {
this.displayMonthIndex = 11;
this.displayYear--;
}
// console.log(this.displayMonthIndex, this.displayYear);
this.displayMonth = months[this.displayMonthIndex] + ' ' + this.displayYear;
this.updateStartDate(this.displayYear, this.displayMonthIndex);
this.updateMonthDays();
});
btnNext.addEventListener('click', event => {
if (this.displayMonthIndex + 1 <= 11) {
this.displayMonthIndex++;
} else {
this.displayMonthIndex = 0;
this.displayYear++;
}
console.log(this.displayMonthIndex, this.displayYear);
this.displayMonth = months[this.displayMonthIndex] + ' ' + this.displayYear;
this.updateStartDate(this.displayYear, this.displayMonthIndex);
this.updateMonthDays();
});
return el;
}
makeMonthTitle() {
this.elTitle = document.createElement('div');
this.elTitle.classList.add(`${baseClass}__month-title`);
this.elTitle.innerHTML = this.displayMonth;
return this.elTitle;
}
makeNavButton(direction) {
if (!directions.hasOwnProperty(direction)) {
throw new Error('Неверный параметр (prev/next)');
}
const el = document.createElement('button');
el.classList.add(`${baseClass}__button`);
el.classList.add(`${baseClass}__button_${directions[direction].cls}`);
el.innerHTML = App.makeSvgIcon(directions[direction].icon, `${baseClass}__btn-icon`);
return el;
}
makeWeekDays() {
const el = document.createElement('div');
el.classList.add(`${baseClass}__weekdays`);
el.innerHTML = weekDays.reduce((acc, cur) => acc + `<div class="${baseClass}__weekday">${cur}</div>`, '');
return el;
}
updateMonthDays(){
let html = '';
let counter = 0;
let isMuted = this.startDate.getDate() !== 1;
let idCounter = 1;
while (counter < 7 * 6) {
let start = this.startDate.getDate();
let mutedClass = isMuted ? ` ${baseClass}__day_muted` : '';
let events = this.events.find(item => {
let d1 = this.startDate.getFullYear().toString()
+ this.startDate.getMonth().toString()
+ this.startDate.getDate().toString();
let _T = new Date(item.date);
let d2 = _T.getFullYear().toString()
+ _T.getMonth().toString()
+ _T.getDate().toString();
return d1 === d2;
});
let pastEvent = false;
if (events) {
let eventDate = new Date(events.date);
if (eventDate < this.today) {
pastEvent = true;
}
}
let innerHtml = `<span>${start}</span>`;
if (events && events.events && events.events.length > 0) {
let eventsHtml = events.events.reduce((p, i) => `${p}<a href="${i.link}">${i.title}</a>`, '');
innerHtml = `<span class="events ${pastEvent
? 'past'
: ''}">${start}<span class="popper" id="iddpr${idCounter++}" hidden>${eventsHtml}</span></span>`;
}
html += `<div class="${baseClass}__day${mutedClass}">${innerHtml}</div>`;
counter++;
this.startDate.setDate(this.startDate.getDate() + 1);
if (this.startDate.getDate() === 1) { isMuted = !isMuted; }
}
this.elDays.innerHTML = html;
}
makeMonthDays() {
this.elDays = document.createElement('div');
this.elDays.classList.add(`${baseClass}__days`);
this.updateMonthDays();
return this.elDays;
}
}
App.calendar = function (el, data) {
if (!el) return;
return new Calendar(el, data);
};
})();
{% include './blocks/header.twig' %}
<div class="my-page">
bla
</div>
{% include './blocks/footer.twig' %}
.button { margin-top: 40px; ... }
<div class="super-block">
<button class="button super-block__button"></button
</div>
.super-block__button { margin-top: 40px; }
<button class="button mt40"></button>
.mt40 { margin-top: 40px; }
Что вы думаете по поводу каскадирования?
4 вариант.
Готовить картинки вручную, одного размера, с одной пропорцией.
Сделать обертку с этой пропорцией (через padding-bottom) и растянуть картинку внутри.