• Как отобрать параметры TV в отдельных вкладках?

    delphinpro
    @delphinpro
    frontend developer
    Тут либо в настройках (вкладка "Интерфейс и представление") стоит настройка группировки TV в новых табах. Тогда просто свои TV поместите в новую группу.
    60591c55a9a11266255772.png

    Либо используется дополнение для кастомизации админки. Устаревший ManagerManager или новый TemplateEdit3.
    Тогда, соответственно, нужно настраивать расположение новых TV в конфигах этих дополнений.
    Ответ написан
    Комментировать
  • Какой вариант записи правильный, li + li или li:last-child?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    Что значит, результат одинаковый?

    li + li {} Выбирает все элементы кроме первого.
    li:last-child {} Выбирает только последний элемент.

    Дополню. Может показаться, что первый вариант идентичен такому:
    li:not(:first-child) {}
    Да, в частном случае. Поэтому стоит быть осторожным. Например в разметке
    div > (a + p + p + p)
    селектор p + p выберет последние два параграфа
    а селектор p:not(:first-child) - все параграфы.
    Ответ написан
  • Что значит defineComponent?

    delphinpro
    @delphinpro
    frontend developer
    https://v3.vuejs.org/api/global-api.html#definecom...

    Вольный перевод:
    Функция ничего не делает, только возвращает переданный объект.
    Нужна для поддержки TypeScript и IDE (автокомплит и прочее)
    Ответ написан
    Комментировать
  • Как правильно организовать код в таком случае?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    В общем, если вам нужно прикрутить логирование, просто установите себе пакет https://github.com/php-fig/log
    И не отвлекайтесь на изобретение велосипеда. Займитесь действительно полезной работой - покрытием логами.
    Ответ написан
  • Как правильно собрать 2 разных js в webpack?

    delphinpro
    @delphinpro Куратор тега JavaScript
    frontend developer
    package.json
    {
        "private": true,
        "scripts": {
            "site:development": "mix",
            "site:watch": "mix watch",
            "site:hot": "mix watch --hot",
            "site:production": "mix --production",
            "dashboard:watch": "cross-env TARGET=dashboard mix watch",
            "dashboard:hot": "cross-env TARGET=dashboard mix watch --hot",
            "dashboard:production": "cross-env TARGET=dashboard mix --production"
        },
        "devDependencies": {
            "browser-sync": "^2.26.14",
            "browser-sync-webpack-plugin": "^2.2.2",
            "chalk": "^4.1.0",
            "cross-env": "^7.0.3",
            "dotenv": "^8.2.0",
            "laravel-mix": "^6.0.13",
            "resolve-url-loader": "^3.1.2",
            "sass": "^1.32.8",
            "sass-loader": "^10.1.1"
        },
        "dependencies": {}
    }

    webpack.mix.js
    /** @type {Api} */
    const mix = require('laravel-mix');
    const path = require('path');
    const dotenv = require('dotenv');
    /** @type {Chalk} */
    const chalk = require('chalk');
    
    const dotEnvLocation = path.resolve('./.env');
    dotenv.config({ path: dotEnvLocation });
    
    const WATCH = process.argv.includes('--watch');
    const HOT = process.argv.includes('--hot');
    const localDomain = process.env.LOCAL_DOMAIN ?? 'localhost';
    const target = process.env.TARGET ?? 'site';
    
    let browserSyncPort = 3000;
    let hmrPort = 8088;
    
    const logs = {
        mode    : WATCH ? chalk.red('WATCH') : HOT ? chalk.red('HOT') : 'None',
        domain  : process.env.LOCAL_DOMAIN ?? chalk.red(localDomain),
        frontend: process.env.FRONTEND_DIST ?? chalk.red(process.env.FRONTEND_DIST),
        backend : process.env.BACKEND_DIST ?? chalk.red(process.env.BACKEND_DIST),
    };
    
    console.log(chalk.cyan('Local domain:  ') + logs.domain);
    console.log(chalk.cyan('Location .env: ') + dotEnvLocation);
    console.log(chalk.cyan('Mode:          ') + logs.mode);
    console.log(chalk.cyan('Public paths:'));
    console.log(chalk.cyan('  Frontend:    ') + logs.frontend);
    console.log(chalk.cyan('  Backend:     ') + logs.backend);
    
    if (target === 'dashboard') {
        browserSyncPort = process.env.BACKEND_LOCAL_PORT ?? 3000;
        hmrPort = process.env.BACKEND_HMR_PORT ?? 8088;
        require('./webpack-dashboard.mix.js');
    }
    
    if (target === 'site') {
        browserSyncPort = process.env.FRONTEND_LOCAL_PORT ?? 3001;
        hmrPort = process.env.FRONTEND_HMR_PORT ?? 8089;
        require('./webpack-site.mix.js');
    }
    
    /*==
     *== Customize options
     *== ======================================= ==*/
    
    mix.version();
    
    mix.disableSuccessNotifications();
    
    if (!HOT && WATCH) {
        mix.browserSync({
            proxy    : localDomain,
            startPath: target === 'site' ? '/' : '/admin',
            browser  : ['chrome'],
            notify   : false,
            port     : browserSyncPort,
        });
    }
    
    mix.options({
        clearConsole: false,
        hmrOptions  : {
            host: 'localhost',
            port: hmrPort,
        },
    });
    
    const webpackResolveRules = {
        extensions: ['*', '.wasm', '.mjs', '.js', '.jsx', '.json', '.vue'],
        alias     : {
            '@': path.join(__dirname, 'resources/js'),
        },
    };
    
    mix.sourceMaps(false, 'source-map');
    
    if (!mix.inProduction()) {
        mix.webpackConfig({
            output : { devtoolModuleFilenameTemplate: '[resource-path]' },
            resolve: webpackResolveRules,
        });
    } else {
        mix.webpackConfig({
            resolve: webpackResolveRules,
        });
    }

    webpack.mix.site.js
    /** @type {Api} */
    const mix = require('laravel-mix');
    
    const HOT = process.argv.includes('--hot');
    
    if (!process.env.FRONTEND_DIST) throw Error;
    
    mix.setPublicPath(`public/${process.env.FRONTEND_DIST}`);
    if (!HOT) mix.setResourceRoot(`/${process.env.FRONTEND_DIST}`);
    
    mix.js('resources/js/app.js', 'js');
    
    mix.sass('resources/scss/app.scss', 'css');
    
    mix.extract();

    webpack.mix.dashboard.js
    /** @type {Api} */
    const mix = require('laravel-mix');
    
    const HOT = process.argv.includes('--hot');
    
    if (!process.env.BACKEND_DIST) throw Error;
    
    mix.setPublicPath(`public/${process.env.BACKEND_DIST}`);
    if (!HOT) mix.setResourceRoot(`/${process.env.BACKEND_DIST}`);
    
    mix.js('resources/dashboard/js/main.js', 'js');
    
    mix.sass('resources/dashboard/scss/main.scss', 'css');
    
    mix.extract();

    .env
    LOCAL_DOMAIN=delphinpro.local
    FRONTEND_LOCAL_PORT=3000
    FRONTEND_HMR_PORT=8003
    FRONTEND_DIST=dist/frontend
    BACKEND_LOCAL_PORT=3004
    BACKEND_HMR_PORT=8004
    BACKEND_DIST=dist/backend

    config/app.php
    <?php
    return [
        // .....
        'frontend' => [
            'dist' => env('FRONTEND_DIST'),
        ],
        'backend' => [
            'dist' => env('BACKEND_DIST'),
        ],
    ];

    *.blage.php
    <link href="{{ mix('css/app.css', config('app.frontend.dist')) }}" rel="stylesheet">
    <script src="{{ mix('js/app.js', config('app.frontend.dist')) }}"></script>
    Ответ написан
    Комментировать
  • Как сделать разные изображения для метатега og:image через php?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    $social_tags['image'] =  $xfieldsdata['screens']
      ?? $xfieldsdata['poster-link']
      ?? ( $xfieldsdata['poster'] ? "/uploads/posts/".$xfieldsdata['poster'] : '/link/to/default.jpg' );
    Ответ написан
    1 комментарий
  • Как прибавлять к сегодняшнему числу еще 7?

    delphinpro
    @delphinpro Куратор тега JavaScript
    frontend developer
    Есть офигительная библиотека momentjs

    moment().add(7, 'days');
    Ответ написан
  • Как функцию stilys скомпилить в sass?

    delphinpro
    @delphinpro Куратор тега Sass
    frontend developer
    Здесь разница только в присваивании. В стайлусе знак "равно", в сасс - "двоеточие"
    $font-size-base: 12px
    $line-height-base: 16px
    text-margin($top, $right, $bottom, $left, $font-size: $font-size-base, $line-height: $line-height-base)
      if $top != 0
        $top: $top - ($line-height - $font-size) / 2
    
      if $bottom != 0
        $bottom: $bottom - ($line-height - $font-size) / 2
    
      margin: $top $right $bottom $left


    Ах, да. Еще как-то определяется функция миксин. Я не помню.
    В нормальном sass это было бы так:

    @mixin text-margin($top, $right, $bottom, $left, $font-size: $font-size-base, $line-height: $line-height-base) {
    
    }
    Ответ написан
    2 комментария
  • Как организовать стили в большом проекте?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    Разбивайте файлы на отдельные блоки. Создайте просто файлы critical.scss и main.scss. В main подключайте всё, в критикал только то, что необходимо для первого экрана.
    Таким образом все ваши стили в основном файле будут организованы как обычно, но вы сможете создавать разные файлы critical для разных страниц.
    Ответ написан
    Комментировать
  • Можно ли использовать absolute в верстке письма?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    Нарезаете картинку на куски. Нужные куски оборачиваете в ссылки.
    Раскладываете все это по ячейкам таблицы.
    Все в лучших традициях верстки прошлого века =))
    Но зато, точно будет отображаться более или менее нормально.

    Насчет огромности картинки. Рекомендованная ширина письма — не более 600-780 пикс.
    Ответ написан
    Комментировать
  • Как сделать Multi auth laravel?

    delphinpro
    @delphinpro Куратор тега Laravel
    frontend developer
    Партнеры вроде как тоже пользователи.
    Можно сделать отдельную таблицу для их данных и связать с User отношением One-to-One
    Ну и роль добавить.
    Ответ написан
  • Overflow-y и overflow-x в slick slide?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    Если есть обрезка по одной стороне, то по второй может быть только обрезка или скролл. Visible может быть только по всем четырем сторонам.

    В такой ситуации можно генерировать выпадающий блок вне слайдера и позиционировать скриптом в нужном месте.
    Ответ написан
  • Как убрать усадку после border?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    a{
      border: 2px solid transparent;
    
      &:hover {
        border-color: red;
      }
    }
    Ответ написан
    1 комментарий
  • Как правильно вернуть ошибку из if?

    delphinpro
    @delphinpro Куратор тега Laravel
    frontend developer
    Вот этот раздел внимательно прочитайте и все вопросы отпадут: https://laravel.com/docs/8.x/validation

    Ru: https://github.com/russsiq/laravel-docs-8.x-ru/blo...
    Ответ написан
    5 комментариев
  • Как правильно хранить использовать на страницах сайта отдельные компоненты Vue?

    delphinpro
    @delphinpro
    frontend developer
    Да не стоит заморачиваться разделением компонентов на отдельные файлы.
    Собирайте один бандл. По крайней мере пока он меньше 200-300kb точно не стоит.
    Потом можно использовать встроенный в webpack code splitter/ Например через magiс comments

    Сами компоненты я монтирую так

    <div id="calculator"></div>

    export function mountVueComponent(targetId, component) {
        if (document.getElementById(targetId)) {
            new (Vue.extend(component))().$mount(`#${targetId}`);
        }
    }


    import Calculator from '....';
    mountVueComponent('calculator', Calculator);


    Или так

    <div class="mini-calc"></div>

    Array.from(document.querySelectorAll('.mini-calc')).forEach(el => {
        let yandexGoal = el.dataset['goal'];
        new Vue({
            el    : el,
            render: createElement => createElement(Calculator, {
                props: {
                    displayAs: CALC_DISPLAY_AS_MINI,
                    yandexGoal,
                },
            }),
        });
    });
    Ответ написан
    Комментировать
  • Как в Laravel отправить данные из формы на email?

    delphinpro
    @delphinpro Куратор тега Laravel
    frontend developer
    artisan make:mail сгенерит вам Mailable класс и шаблон.
    Все публичные поля этого класса будут доступны в шаблоне как переменные.
    Для отправки просто вызываете

    Mail::to($user->email)
      ->send(new RegistrationMail($user));
    Ответ написан
  • Как вернуть широкую полосу прокрутки Youtube?

    delphinpro
    @delphinpro
    frontend developer
    Установить расширение для стилизации страниц. Например stylish или аналоги.
    Добавить стиль для сайта ютуба

    body:not(.style-scope)[themed-scrollbar]:not(.style-scope):not([no-y-overflow]):not(.style-scope)::-webkit-scrollbar {
      width: 16px !important;
    }
    Ответ написан
    4 комментария
  • Фильтрация данных?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    пароль htmlspecialchars для перестраховки

    зачем?
    htmlspecialchars кодирует служебные символы html. Зачем ее применять для пароля?
    И вообще, пароль у вас никогда нигде не хранится в открытом виде, только его хеш и то внутри системы.

    минимальную фильтрацию где это необходимо

    верное направление мысли.

    Необходимо в двух местах:
    1. запись базу
    2. вывод на страницу

    Чтобы защититься от sql-injection при записи, используйте подготовленные запросы.
    Чтобы не сломать верстку при выводе данных — используйте htmlspecialchars при рендере страницы. А лучше возьмите шаблонизатор. Они все по умолчанию эскейпят вывод.

    разрешить в логин и имя только a-zа-яё0-9


    Это уже не фильтрация, а валидация данных, к безопасности особого отношения не имеет и выполняется в других местах приложения.
    Простой пример. Пользователь отправил форму.
    Вы первым делом сделаете проверку всех полей на допустимые значения, на заполненность и т.д., и если что вернете посетителя обратно на форму с указанием ошибки. Данные здесь не изменяются.
    Если все в порядке, вы будете писать эти данные в базу. Как я уже написал, используя подготовленный запрос. Опять же, ничего менять в них не требуется.
    Потом, вы будете эту информацию где-то выводить на странице. Вот здесь уже, перед выводом, вы прогоните все через htmlspecialchars, возможно какие-то еще корректировки сделаете.

    Но, опять же вы пишете про универсальную фильтрацию на все случаи. Так не бывает.
    Если вы ожидаете во входных данных исключительно текст, то можно, например, смело резать все теги перед записью в базу. А если вы получаете их из визуального редактора, с разметкой, то резать теги уже не нужно.
    Ответ написан
    2 комментария
  • Как сделать полоску над активным пунктом меню css?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    Теоретически, вы можете сделать подобное без использования javascript



    Но это не универсальный хардкод.

    Поэтому, лучше все же использовать js для позиционирования полоски.
    Ответ написан
    Комментировать
  • Как сделать такой слайдер?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    Сделайте два слайда и весь слайдер чуть-чуть задвиньте вправо, на пол-слайда,
    Ответ написан
    Комментировать