├── .ddev └── config.yaml ├── .editorconfig ├── .env.example ├── .eslintrc.js ├── .gitattributes ├── .github └── workflows │ └── tests.yml ├── .gitignore ├── .gitlab-ci.yml ├── .nvmrc ├── .prettierrc.js ├── .stylelintrc.js ├── CHANGELOG.md ├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── config └── scaffold │ └── web │ ├── .htaccess │ └── wp-config.php ├── data └── .gitkeep ├── jsconfig.json ├── meta.config.mjs ├── package-lock.json ├── package.json ├── phpcs.xml ├── phpstan.neon ├── scripts ├── create-project.php ├── functions │ ├── autoload.php │ ├── get-salts.php │ ├── random.php │ ├── run-commands.php │ └── update-file.php └── get-wp-salts.php ├── tailwind.config.js ├── tailwind.safelist.txt ├── web ├── index.php └── wp-content │ ├── languages │ └── .gitkeep │ ├── mu-plugins │ ├── .gitkeep │ └── studiometa-plugin-disabler │ │ ├── README.md │ │ ├── includes │ │ └── class-disableplugins.php │ │ ├── studiometa-plugin-disabler.php │ │ └── uninstall.php │ ├── plugins │ └── .gitkeep │ └── themes │ ├── .gitkeep │ └── studiometa │ ├── 404.php │ ├── app │ ├── Blocks │ │ ├── AbstractBlock.php │ │ ├── Accordion.php │ │ ├── BlockInterface.php │ │ ├── Image.php │ │ ├── ImageText.php │ │ ├── README.md │ │ ├── Text.php │ │ └── Video.php │ ├── Managers │ │ ├── ACFManager.php │ │ ├── CustomPostTypesManager.php │ │ ├── README.md │ │ ├── TaxonomiesManager.php │ │ ├── ThemeManager.php │ │ ├── TinyMCEManager.php │ │ ├── TwigManager.php │ │ └── WordPressManager.php │ ├── Models │ │ ├── Page.php │ │ ├── Post.php │ │ └── README.md │ ├── Repositories │ │ ├── PostRepository.php │ │ ├── README.md │ │ ├── Repository.php │ │ └── TermRepository.php │ └── Services │ │ └── README.md │ ├── archive.php │ ├── config │ ├── .gitkeep │ └── assets.yml │ ├── footer.php │ ├── front-page.php │ ├── functions.php │ ├── header.php │ ├── index.php │ ├── page-template-builder.php │ ├── page.php │ ├── search.php │ ├── sidebar.php │ ├── single.php │ ├── src │ ├── css │ │ ├── _config.scss │ │ ├── admin │ │ │ └── editor-style.scss │ │ ├── app.scss │ │ ├── atoms │ │ │ ├── .gitkeep │ │ │ └── _index.scss │ │ ├── base │ │ │ ├── .gitkeep │ │ │ └── _index.scss │ │ ├── molecules │ │ │ ├── .gitkeep │ │ │ └── _index.scss │ │ ├── organisms │ │ │ ├── .gitkeep │ │ │ ├── _index.scss │ │ │ └── blocks │ │ │ │ └── _wysiwyg.scss │ │ └── utilities │ │ │ ├── .gitkeep │ │ │ └── _index.scss │ └── js │ │ ├── app.js │ │ ├── atoms │ │ └── .gitkeep │ │ ├── config.js │ │ ├── molecules │ │ ├── .gitkeep │ │ ├── Accordion.js │ │ ├── Component.js │ │ └── Video.js │ │ ├── organisms │ │ └── .gitkeep │ │ └── utils │ │ └── .gitkeep │ ├── static │ ├── fonts │ │ └── .gitkeep │ ├── img │ │ └── .gitkeep │ └── svg │ │ ├── .gitkeep │ │ └── play.svg │ ├── style.css │ └── templates │ ├── atoms │ └── .gitkeep │ ├── layouts │ └── base.twig │ ├── molecules │ ├── .gitkeep │ └── video.twig │ ├── organisms │ ├── blocks │ │ ├── block-accordion.twig │ │ ├── block-image-text.twig │ │ ├── block-image.twig │ │ ├── block-text.twig │ │ ├── block-video.twig │ │ └── default.twig │ ├── footer-menu.twig │ ├── footer.twig │ ├── header.twig │ ├── menu.twig │ ├── pagination.twig │ ├── tease-post.twig │ └── tease.twig │ └── pages │ ├── 404.twig │ ├── archive.twig │ ├── front-page.twig │ ├── index.twig │ ├── page-plugin.twig │ ├── page-template-builder.twig │ ├── page.twig │ ├── search.twig │ ├── single-password.twig │ └── single.twig └── wp-cli.yml /.ddev/config.yaml: -------------------------------------------------------------------------------- 1 | name: wordpress-project 2 | type: wordpress 3 | docroot: web 4 | php_version: "7.3" 5 | webserver_type: apache-fpm 6 | router_http_port: "80" 7 | router_https_port: "443" 8 | xdebug_enabled: false 9 | additional_hostnames: [] 10 | additional_fqdns: [] 11 | database: 12 | type: mariadb 13 | version: "10.3" 14 | nfs_mount_enabled: false 15 | mutagen_enabled: false 16 | use_dns_when_possible: true 17 | composer_version: "2" 18 | disable_settings_management: true 19 | web_environment: [] 20 | nodejs_version: "16" 21 | 22 | # Key features of ddev's config.yaml: 23 | 24 | # name: # Name of the project, automatically provides 25 | # http://projectname.ddev.site and https://projectname.ddev.site 26 | 27 | # type: # drupal6/7/8, backdrop, typo3, wordpress, php 28 | 29 | # docroot: # Relative path to the directory containing index.php. 30 | 31 | # php_version: "7.4" # PHP version to use, "5.6", "7.0", "7.1", "7.2", "7.3", "7.4", "8.0", "8.1" 32 | 33 | # You can explicitly specify the webimage but this 34 | # is not recommended, as the images are often closely tied to ddev's' behavior, 35 | # so this can break upgrades. 36 | 37 | # webimage: # nginx/php docker image. 38 | 39 | # database: 40 | # type: # mysql, mariadb 41 | # version: # database version, like "10.3" or "8.0" 42 | # Note that mariadb_version or mysql_version from v1.18 and earlier 43 | # will automatically be converted to this notation with just a "ddev config --auto" 44 | 45 | # router_http_port: # Port to be used for http (defaults to port 80) 46 | # router_https_port: # Port for https (defaults to 443) 47 | 48 | # xdebug_enabled: false # Set to true to enable xdebug and "ddev start" or "ddev restart" 49 | # Note that for most people the commands 50 | # "ddev xdebug" to enable xdebug and "ddev xdebug off" to disable it work better, 51 | # as leaving xdebug enabled all the time is a big performance hit. 52 | 53 | # xhprof_enabled: false # Set to true to enable xhprof and "ddev start" or "ddev restart" 54 | # Note that for most people the commands 55 | # "ddev xhprof" to enable xhprof and "ddev xhprof off" to disable it work better, 56 | # as leaving xhprof enabled all the time is a big performance hit. 57 | 58 | # webserver_type: nginx-fpm # or apache-fpm 59 | 60 | # timezone: Europe/Berlin 61 | # This is the timezone used in the containers and by PHP; 62 | # it can be set to any valid timezone, 63 | # see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones 64 | # For example Europe/Dublin or MST7MDT 65 | 66 | # composer_root: 67 | # Relative path to the composer root directory from the project root. This is 68 | # the directory which contains the composer.json and where all Composer related 69 | # commands are executed. 70 | 71 | # composer_version: "2" 72 | # You can set it to "" or "2" (default) for Composer v2 or "1" for Composer v1 73 | # to use the latest major version available at the time your container is built. 74 | # It is also possible to select a minor version for example "2.2" which will 75 | # install the latest release of that branch. Alternatively, an explicit Composer 76 | # version may be specified, for example "1.0.22". Finally, it is also possible 77 | # to use one of the key words "stable", "preview" or "snapshot" see Composer 78 | # documentation. 79 | # To reinstall Composer after the image was built, run "ddev debug refresh". 80 | 81 | # nodejs_version: "16" 82 | # change from the default system Node.js version to another supported version, like 12, 14, 17, 18. 83 | # Note that you can use 'ddev nvm' or nvm inside the web container to provide nearly any 84 | # Node.js version, including v6, etc. 85 | 86 | # additional_hostnames: 87 | # - somename 88 | # - someothername 89 | # would provide http and https URLs for "somename.ddev.site" 90 | # and "someothername.ddev.site". 91 | 92 | # additional_fqdns: 93 | # - example.com 94 | # - sub1.example.com 95 | # would provide http and https URLs for "example.com" and "sub1.example.com" 96 | # Please take care with this because it can cause great confusion. 97 | 98 | # upload_dir: custom/upload/dir 99 | # would set the destination path for ddev import-files to /custom/upload/dir 100 | # When mutagen is enabled this path is bind-mounted so that all the files 101 | # in the upload_dir don't have to be synced into mutagen 102 | 103 | # working_dir: 104 | # web: /var/www/html 105 | # db: /home 106 | # would set the default working directory for the web and db services. 107 | # These values specify the destination directory for ddev ssh and the 108 | # directory in which commands passed into ddev exec are run. 109 | 110 | # omit_containers: [db, dba, ddev-ssh-agent] 111 | # Currently only these containers are supported. Some containers can also be 112 | # omitted globally in the ~/.ddev/global_config.yaml. Note that if you omit 113 | # the "db" container, several standard features of ddev that access the 114 | # database container will be unusable. In the global configuration it is also 115 | # possible to omit ddev-router, but not here. 116 | 117 | # nfs_mount_enabled: false 118 | # Great performance improvement but requires host configuration first. 119 | # See https://ddev.readthedocs.io/en/stable/users/performance/#using-nfs-to-mount-the-project-into-the-container 120 | 121 | # mutagen_enabled: false 122 | # Performance improvement using mutagen asynchronous updates. 123 | # See https://ddev.readthedocs.io/en/latest/users/performance/#using-mutagen 124 | 125 | # fail_on_hook_fail: False 126 | # Decide whether 'ddev start' should be interrupted by a failing hook 127 | 128 | # host_https_port: "59002" 129 | # The host port binding for https can be explicitly specified. It is 130 | # dynamic unless otherwise specified. 131 | # This is not used by most people, most people use the *router* instead 132 | # of the localhost port. 133 | 134 | # host_webserver_port: "59001" 135 | # The host port binding for the ddev-webserver can be explicitly specified. It is 136 | # dynamic unless otherwise specified. 137 | # This is not used by most people, most people use the *router* instead 138 | # of the localhost port. 139 | 140 | # host_db_port: "59002" 141 | # The host port binding for the ddev-dbserver can be explicitly specified. It is dynamic 142 | # unless explicitly specified. 143 | 144 | # phpmyadmin_port: "8036" 145 | # phpmyadmin_https_port: "8037" 146 | # The PHPMyAdmin ports can be changed from the default 8036 and 8037 147 | 148 | # host_phpmyadmin_port: "8036" 149 | # The phpmyadmin (dba) port is not normally bound on the host at all, instead being routed 150 | # through ddev-router, but it can be specified and bound. 151 | 152 | # mailhog_port: "8025" 153 | # mailhog_https_port: "8026" 154 | # The MailHog ports can be changed from the default 8025 and 8026 155 | 156 | # host_mailhog_port: "8025" 157 | # The mailhog port is not normally bound on the host at all, instead being routed 158 | # through ddev-router, but it can be bound directly to localhost if specified here. 159 | 160 | # webimage_extra_packages: [php7.4-tidy, php-bcmath] 161 | # Extra Debian packages that are needed in the webimage can be added here 162 | 163 | # dbimage_extra_packages: [telnet,netcat] 164 | # Extra Debian packages that are needed in the dbimage can be added here 165 | 166 | # use_dns_when_possible: true 167 | # If the host has internet access and the domain configured can 168 | # successfully be looked up, DNS will be used for hostname resolution 169 | # instead of editing /etc/hosts 170 | # Defaults to true 171 | 172 | # project_tld: ddev.site 173 | # The top-level domain used for project URLs 174 | # The default "ddev.site" allows DNS lookup via a wildcard 175 | # If you prefer you can change this to "ddev.local" to preserve 176 | # pre-v1.9 behavior. 177 | 178 | # ngrok_args: --basic-auth username:pass1234 179 | # Provide extra flags to the "ngrok http" command, see 180 | # https://ngrok.com/docs#http or run "ngrok http -h" 181 | 182 | # disable_settings_management: false 183 | # If true, ddev will not create CMS-specific settings files like 184 | # Drupal's settings.php/settings.ddev.php or TYPO3's AdditionalConfiguration.php 185 | # In this case the user must provide all such settings. 186 | 187 | # You can inject environment variables into the web container with: 188 | # web_environment: 189 | # - SOMEENV=somevalue 190 | # - SOMEOTHERENV=someothervalue 191 | 192 | # no_project_mount: false 193 | # (Experimental) If true, ddev will not mount the project into the web container; 194 | # the user is responsible for mounting it manually or via a script. 195 | # This is to enable experimentation with alternate file mounting strategies. 196 | # For advanced users only! 197 | 198 | # bind_all_interfaces: false 199 | # If true, host ports will be bound on all network interfaces, 200 | # not just the localhost interface. This means that ports 201 | # will be available on the local network if the host firewall 202 | # allows it. 203 | 204 | # default_container_timeout: 120 205 | # The default time that ddev waits for all containers to become ready can be increased from 206 | # the default 120. This helps in importing huge databases, for example. 207 | 208 | #web_extra_exposed_ports: 209 | #- name: nodejs 210 | # container_port: 3000 211 | # http_port: 2999 212 | # https_port: 3000 213 | #- name: something 214 | # container_port: 4000 215 | # https_port: 4000 216 | # http_port: 3999 217 | # Allows a set of extra ports to be exposed via ddev-router 218 | # The port behavior on the ddev-webserver must be arranged separately, for example 219 | # using web_extra_daemons. 220 | # For example, with a web app on port 3000 inside the container, this config would 221 | # expose that web app on https://.ddev.site:9999 and http://.ddev.site:9998 222 | # web_extra_exposed_ports: 223 | # - container_port: 3000 224 | # http_port: 9998 225 | # https_port: 9999 226 | 227 | #web_extra_daemons: 228 | #- name: "http-1" 229 | # command: "/var/www/html/node_modules/.bin/http-server -p 3000" 230 | # directory: /var/www/html 231 | #- name: "http-2" 232 | # command: "/var/www/html/node_modules/.bin/http-server /var/www/html/sub -p 3000" 233 | # directory: /var/www/html 234 | 235 | # override_config: false 236 | # By default, config.*.yaml files are *merged* into the configuration 237 | # But this means that some things can't be overridden 238 | # For example, if you have 'nfs_mount_enabled: true'' you can't override it with a merge 239 | # and you can't erase existing hooks or all environment variables. 240 | # However, with "override_config: true" in a particular config.*.yaml file, 241 | # 'nfs_mount_enabled: false' can override the existing values, and 242 | # hooks: 243 | # post_start: [] 244 | # or 245 | # web_environment: [] 246 | # or 247 | # additional_hostnames: [] 248 | # can have their intended affect. 'override_config' affects only behavior of the 249 | # config.*.yaml file it exists in. 250 | 251 | # Many ddev commands can be extended to run tasks before or after the 252 | # ddev command is executed, for example "post-start", "post-import-db", 253 | # "pre-composer", "post-composer" 254 | # See https://ddev.readthedocs.io/en/stable/users/extend/custom-commands/ for more 255 | # information on the commands that can be extended and the tasks you can define 256 | # for them. Example: 257 | #hooks: 258 | # Un-comment to emit the WP CLI version after ddev start. 259 | # post-start: 260 | # - exec: wp cli version 261 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [*.php] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | APP_HOST="${DDEV_HOSTNAME}" 2 | APP_ENV=local # local | preprod | production 3 | APP_DEBUG=true # true | false 4 | APP_SSL=true # true | false 5 | 6 | DB_HOST=db 7 | DB_DATABASE=db 8 | DB_USERNAME=db 9 | DB_PASSWORD=db 10 | DB_PREFIX=wp_ 11 | 12 | DISABLE_PLUGINS_LOCAL=test/test.php 13 | DISABLE_PLUGINS_PREPROD=test/test.php 14 | DISABLE_PLUGINS_PRODUCTION=test/test.php 15 | 16 | AUTH_KEY='' 17 | SECURE_AUTH_KEY='' 18 | LOGGED_IN_KEY='' 19 | NONCE_KEY='' 20 | AUTH_SALT='' 21 | SECURE_AUTH_SALT='' 22 | LOGGED_IN_SALT='' 23 | NONCE_SALT='' 24 | 25 | # WP Rocket config 26 | WP_ROCKET_EMAIL='' 27 | WP_ROCKET_KEY='' 28 | WP_CACHE=false 29 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: '@studiometa/eslint-config', 3 | }; 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | /web/wp-content/themes/studiometa/dist/** -text -diff 2 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish 2 | # a package to NPM Packages when a release is created. 3 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages 4 | 5 | name: Tests 6 | 7 | on: 8 | push: 9 | branches: 10 | - master 11 | - develop 12 | pull_request: 13 | 14 | jobs: 15 | phpcs: 16 | name: PHPCS 17 | runs-on: ubuntu-latest 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | # @todo PHP 8.0 22 | php-versions: ['7.3'] 23 | composer-versions: ['v1', 'v2'] 24 | steps: 25 | - name: Checkout code 26 | uses: actions/checkout@v2 27 | 28 | - name: Setup PHP, with composer and xdebug 29 | uses: shivammathur/setup-php@v2 # https://github.com/shivammathur/setup-php 30 | with: 31 | php-version: ${{ matrix.php-versions }} 32 | tools: composer:${{ matrix.composer-versions }} 33 | env: 34 | COMPOSER_AUTH_JSON: ${{ secrets.COMPOSER_AUTH_JSON }} 35 | 36 | - name: Get composer cache directory 37 | id: composer-cache 38 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 39 | 40 | - name: Cache composer dependencies 41 | uses: actions/cache@v2 42 | with: 43 | path: ${{ steps.composer-cache.outputs.dir }} 44 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} 45 | restore-keys: ${{ runner.os }}-composer- 46 | 47 | - name: Install Composer dependencies 48 | run: composer install --no-progress --prefer-dist --optimize-autoloader 49 | 50 | - name: PHPCS 51 | run: composer run phpcs 52 | 53 | phpstan: 54 | name: PHPStan 55 | runs-on: ubuntu-latest 56 | steps: 57 | - name: Checkout code 58 | uses: actions/checkout@v2 59 | 60 | - name: Setup PHP, with composer and xdebug 61 | uses: shivammathur/setup-php@v2 # https://github.com/shivammathur/setup-php 62 | with: 63 | php-version: '7.3' 64 | tools: composer:v2 65 | env: 66 | COMPOSER_AUTH_JSON: ${{ secrets.COMPOSER_AUTH_JSON }} 67 | 68 | - name: Get composer cache directory 69 | id: composer-cache 70 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 71 | 72 | - name: Cache composer dependencies 73 | uses: actions/cache@v2 74 | with: 75 | path: ${{ steps.composer-cache.outputs.dir }} 76 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} 77 | restore-keys: ${{ runner.os }}-composer- 78 | 79 | - name: Install Composer dependencies 80 | run: composer install --no-progress --prefer-dist --optimize-autoloader 81 | 82 | - name: PHPStan 83 | run: composer run phpstan 84 | 85 | eslint: 86 | name: ESLint 87 | runs-on: ubuntu-latest 88 | steps: 89 | - name: Checkout code 90 | uses: actions/checkout@v2 91 | 92 | - uses: actions/setup-node@v2 93 | with: 94 | node-version: 16 95 | cache: npm 96 | - name: Install modules 97 | run: npm install 98 | 99 | - run: npm run lint:scripts 100 | 101 | stylelint: 102 | name: Stylelint 103 | runs-on: ubuntu-latest 104 | steps: 105 | - name: Checkout code 106 | uses: actions/checkout@v2 107 | 108 | - uses: actions/setup-node@v2 109 | with: 110 | node-version: 16 111 | cache: npm 112 | - name: Install modules 113 | run: npm install 114 | 115 | - run: npm run lint:styles 116 | 117 | prettier: 118 | name: Twig Prettier 119 | runs-on: ubuntu-latest 120 | steps: 121 | - name: Checkout code 122 | uses: actions/checkout@v2 123 | 124 | - uses: actions/setup-node@v2 125 | with: 126 | node-version: 16 127 | cache: npm 128 | - name: Install modules 129 | run: npm install 130 | 131 | - run: npm run lint:templates 132 | 133 | build-assets: 134 | name: Build assets 135 | runs-on: ubuntu-latest 136 | steps: 137 | - name: Checkout code 138 | uses: actions/checkout@v2 139 | 140 | - uses: actions/setup-node@v2 141 | with: 142 | node-version: 16 143 | cache: npm 144 | - name: Install modules 145 | run: npm install 146 | 147 | - run: npm run build 148 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS et IDE files 2 | .DS_Store 3 | .idea/ 4 | .vscode/ 5 | *.sublime-projet 6 | *.sublime-workspace 7 | *.log 8 | 9 | # Ignore directories generated by NPM 10 | /node_modules/ 11 | 12 | # Ignore directories generated by Composer 13 | /composer.phar 14 | /vendor/ 15 | 16 | # Ignore data 17 | /data/* 18 | !/data/.gitkeep 19 | 20 | # Ignore Wordpress install directory 21 | /web/wp/ 22 | 23 | # Ignore dynamic files that might be edited by WordPress 24 | /web/.htaccess 25 | /web/wp-content/db.php 26 | /web/wp-content/advanced-cache.php 27 | 28 | # Ignore mu-plugins, plugins and themes installed via composer 29 | # but do not ignore custom ones for the current project 30 | /web/wp-content/*/* 31 | !/web/wp-content/*/.gitkeep 32 | 33 | # Add exception for the project's theme and plugins 34 | !/web/wp-content/themes/studiometa 35 | !/web/wp-content/mu-plugins/studiometa-plugin-disabler/ 36 | !/web/wp-content/plugins/acfml 37 | !/web/wp-content/plugins/sitepress-multilingual-cms 38 | !/web/wp-content/plugins/wpml-string-translation 39 | !/web/wp-content/plugins/wpml-translation-management 40 | !/web/wp-content/plugins/gravityforms 41 | !/web/wp-content/plugins/gravityforms-multilingual 42 | # !/web/wp-content/mu-plugins/... 43 | 44 | # Ignore .env and config files as they are personal 45 | .env 46 | .htpasswd 47 | /web/wp-config.php 48 | 49 | # Theme dynamic assets 50 | /web/wp-content/themes/studiometa/dist/ 51 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | NODE_VERSION: 16 3 | PHP_VERSION: '7.3' 4 | DDEV_PROJECT_NAME: wordpress-project 5 | 6 | # External job definitions 7 | include: 8 | - project: studiometa/gitlab-ci 9 | ref: 2.x 10 | file: 11 | - config/bot/create-merge-request.yml 12 | - config/bot/gitflow-release-auto-tag.yml 13 | - config/node/npm-install.yml 14 | - config/node/eslint.yml 15 | - config/node/stylelint.yml 16 | - config/node/prettier.yml 17 | - config/php/composer-install.yml 18 | - config/php/phpcs.yml 19 | - config/php/phpstan.yml 20 | - config/deploy/ddev/preprod.yml 21 | - config/deploy/ddev/preview.yml 22 | - config/release/gitlab.yml 23 | 24 | node_eslint: 25 | variables: 26 | ESLINT_ARGS: 'web/wp-content/themes/studiometa/src/**/*.{js,jsx}' 27 | 28 | node_stylelint: 29 | variables: 30 | STYLELINT_ARGS: 'web/wp-content/themes/studiometa/src/**/*.scss' 31 | 32 | node_prettier: 33 | variables: 34 | PRETTIER_ARGS: 'web/wp-content/themes/studiometa/templates/**/*.twig' 35 | 36 | php_phpcs: 37 | variables: 38 | PHPCS_ARGS: --extensions=php --standard=./phpcs.xml --report=\\Satesh\\Phpcs\\GitLabReport --report-file=gl-phpcs-codequality.json 39 | 40 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 16 2 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@studiometa/prettier-config'); 2 | -------------------------------------------------------------------------------- /.stylelintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: '@studiometa/stylelint-config', 3 | }; 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | Tous les changements notables de ce projet seront documentés dans ce fichier. Le format est basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/), et ce projet suit les règles du [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 4 | 5 | ## Non publié 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Studio Meta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WordPress project 2 | 3 | ## Initialiser un nouveau projet 4 | ```bash 5 | composer create-project studiometa/wordpress-project www.fqdn.com 6 | ``` 7 | 8 | ## Installation 9 | 10 | Créer et configurer le fichier `.env` en vous basant sur le fichier `.env.example`. 11 | Créer et configurer le fichier `.htaccess` en vous basant sur le fichier `.htaccess.example`. 12 | 13 | Installer les dépendances nécessaires : 14 | 15 | ```bash 16 | # Installer les dépendances Composer avec PHP 7.3 17 | php7.3 $(which composer) install 18 | 19 | # Installer les dépendances NPM avec Node 16 20 | nvm use 16 21 | npm install 22 | ``` 23 | 24 | Utiliser [wp-cli](https://wp-cli.org/fr/) pour finaliser l'installation. Si vous utiliser `ddev` préfixer votre commande : `ddev wp` sinon lancer la commande depuis le dossier vendor: `/vendor/bin/wp ` 25 | ```bash 26 | /vendor/bin/wp 27 | 28 | # Créer la base de donnée (non nécessaire si vous utilisez ddev) 29 | /vendor/bin/wp db create 30 | 31 | # Installer WordPress 32 | /vendor/bin/wp core install --url="{URL_DU_SITE}" --title="{TITLE_DU_SITE}" --admin_user="{ADMIN_USER}" --admin_email="{ADMIN_EMAIL}" 33 | 34 | # Installer la langue FR 35 | /vendor/bin/wp language core install fr_FR 36 | 37 | # Activer la langue FR 38 | /vendor/bin/wp site switch-language 39 | 40 | # Activer les plugins WordPress 41 | /vendor/bin/wp plugin activate classic-editor advanced-custom-fields-pro seo-by-rank-math 42 | ``` 43 | 44 | ## Développement 45 | 46 | ### Commandes disponibles 47 | 48 | #### NPM 49 | 50 | | Commande | Description | 51 | |-|-| 52 | | `npm run dev` | Démarre le serveur de compilation des fichiers SCSS et JS du thème. | 53 | | `npm run build` | Build les fichiers SCSS, JS et Vue du thème. | 54 | | `npm run lint` | Lint les fichiers SCSS, JS, Vue et Twig du thème avec ESLint, Stylelint et Prettier. | 55 | | `npm run lint:scipts` | Lint les fichiers JS et Vue du thème avec ESLint et Prettier. | 56 | | `npm run lint:styles` | Lint les fichiers SCSS et Vue du thème avec Stylelint et Prettier. | 57 | | `npm run lint:templates` | Lint les fichiers Twig avec Prettier. | 58 | | `npm run fix` | Formate les fichiers SCSS, JS, Vue et Twig du thème avec ESLint, Stylelint et Prettier. | 59 | | `npm run fix:scipts` | Formate les fichiers JS et Vue du thème avec ESLint et Prettier. | 60 | | `npm run fix:styles` | Formate les fichiers SCSS et Vue du thème avec Stylelint et Prettier. | 61 | | `npm run fix:templates` | Formate les fichiers Twig du thème Prettier. | 62 | 63 | 64 | #### Composer 65 | 66 | | Commande | Description | 67 | |-|-| 68 | | `composer phpcs` | Lint les fichiers PHP du thème et des plugins customs | 69 | | `composer phpstan` | Analyse de manière statiques les fichiers PHP du thème et des plugins customs | 70 | 71 | 72 | #### WP CLI 73 | 74 | Une liste (non exaustive) des commandes utiles de [WPCLI](https://wp-cli.org/fr/) 75 | 76 | > Si wp cli est installé sur votre machine et configuré dans votre $PATH utiliser les commandes ci-dessous, sinon utiliser `./vendor/bin/wp` 77 | 78 | | Commande | Description | 79 | |-|-| 80 | | `wp user create --role= --user_pass=` | Créer un utilisateur | 81 | | `wp transient delete --all` | Supprimer tous les transients de la base de données | 82 | | `wp post delete $(wp post list --post_type='revision' --format=ids) --force` | Supprimer toutes les révisions | 83 | | `wp plugin activate` | Activer un plugin | 84 | | `wp plugin deactivate` | Désactiver un plugin | 85 | | `wp search-replace 'http://old-domain.com/' 'http://new-domain.com/' --precise --recurse-objects --all-tables-with-prefix` | Remplacer toutes les URL's pour migrer une base de données. ⚠ Faire un backup avant de lancer cette commande, ajouter le paramètre `–dry-run` pour lancer la commande sans effectuer de changements | 86 | | `wp language core install fr_FR && wp language core activate fr_FR` | Installer une nouvelle langue de back-office (changer `fr_FR` par la langue souhaitée) | 87 | 88 | 89 | ### Ajouter des plugins et mu-plugins 90 | 91 | Pour ajouter des plugins et mu-plugins tiers, utilisez Composer avec l'aide de [wpackagist.org](https://wpackagist.org/). Par exemple, pour ajouter le plugin [Classic Editor](), vous pouvez procéder comme suit : 92 | 93 | ```bash 94 | composer require wpackagist/classic-editor 95 | ``` 96 | 97 | Par défaut, tout ce qui se trouve dans les sous-dossiers de `web/wp-content` est ignoré par Git pour éviter de suivre les packages tiers installés avec Composer. Pour ajouter vos plugins et thèmes personnalisés à votre dépôt Git, vous devez ajouter des règles dans le fichier `.gitignore` : 98 | 99 | ``` 100 | !/web/wp-content/mu-plugins/my-mu-plugin.php 101 | !/web/wp-content/plugins/my-plugin/ 102 | ``` 103 | 104 | ## Fonctionnalités additionnelles 105 | 106 | ### Désactivation de plugins par environnement 107 | 108 | Le MU-plugin [Studiometa plugin disabler](./web/wp-content/mu-plugins/studiometa-plugin-disabler/README.md) permet de forcer la désactivation des plugins en fonction de l'environnement. [Voir le readme](./web/wp-content/mu-plugins/studiometa-plugin-disabler/README.md) pour plus d'informations. 109 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "studiometa/wordpress-project", 3 | "type": "project", 4 | "authors": [ 5 | { 6 | "name": "Studio Meta", 7 | "email": "agence@studiometa.fr" 8 | } 9 | ], 10 | "license": "MIT", 11 | "require": { 12 | "php": "^7.3", 13 | "vlucas/phpdotenv": "^5.5.0", 14 | "johnpbloch/wordpress": "6.*", 15 | "timber/timber": "^1.20", 16 | "studiometa/wp-toolkit": "^1.0", 17 | "wp-media/wp-rocket": "^3.11", 18 | "wpackagist-plugin/classic-editor": "^1.6", 19 | "wpackagist-plugin/seo-by-rank-math": "^1.0", 20 | "studiometa/advanced-custom-fields-pro": "^6.1.4", 21 | "stoutlogic/acf-builder": "^1.12", 22 | "boxuk/wp-muplugin-loader": "^2.0", 23 | "djboris88/twig-commented-include": "^1.2", 24 | "studiometa/ui": "^0.2.31" 25 | }, 26 | "require-dev": { 27 | "wpackagist-plugin/query-monitor": "^3.9", 28 | "squizlabs/php_codesniffer": "^3.7", 29 | "wp-coding-standards/wpcs": "^2.3", 30 | "wp-cli/wp-cli-bundle": "^2.6", 31 | "dealerdirect/phpcodesniffer-composer-installer": "^1.0.0", 32 | "phpstan/phpstan": "^1.7", 33 | "szepeviktor/phpstan-wordpress": "^1.1", 34 | "satesh/phpcs-gitlab-report": "^1.0", 35 | "phpcompatibility/phpcompatibility-wp": "^2.1", 36 | "roave/security-advisories": "dev-latest", 37 | "mikehaertl/php-shellcommand": "^1.6" 38 | }, 39 | "repositories": [ 40 | { 41 | "type": "composer", 42 | "url": "https://gitlab.studiometa.dev/api/v4/group/73/-/packages/composer/" 43 | }, 44 | { 45 | "type": "composer", 46 | "url": "https://wpackagist.org" 47 | } 48 | ], 49 | "scripts": { 50 | "post-create-project-cmd": [ 51 | "@php scripts/create-project.php" 52 | ], 53 | "post-install-cmd": [ 54 | "rm -rf ./web/wp/wp-content", 55 | "cp config/scaffold/web/wp-config.php web/wp-config.php", 56 | "cp config/scaffold/web/.htaccess web/.htaccess" 57 | ], 58 | "post-update-cmd": [ 59 | "rm -rf ./web/wp/wp-content", 60 | "cp config/scaffold/web/wp-config.php web/wp-config.php", 61 | "cp config/scaffold/web/.htaccess web/.htaccess" 62 | ], 63 | "phpstan": "phpstan analyse --memory-limit=512M", 64 | "test": "echo 'No test specified' && exit 0", 65 | "phpcs": "phpcs --cache -p -s --colors --extensions=php --standard=./phpcs.xml" 66 | }, 67 | "config": { 68 | "optimize-autoloader": true, 69 | "allow-plugins": { 70 | "boxuk/wp-muplugin-loader": true, 71 | "johnpbloch/wordpress-core-installer": true, 72 | "composer/installers": true, 73 | "dealerdirect/phpcodesniffer-composer-installer": true 74 | } 75 | }, 76 | "autoload": { 77 | "psr-4": { 78 | "Studiometa\\": "web/wp-content/themes/studiometa/app" 79 | } 80 | }, 81 | "extra": { 82 | "installer-types": [ 83 | "library", 84 | "wordpress-plugin", 85 | "wordpress-theme", 86 | "wordpress-muplugin", 87 | "wordpress-dropin" 88 | ], 89 | "installer-paths": { 90 | "web/wp-content/plugins/{$name}/": [ 91 | "type:wordpress-plugin" 92 | ], 93 | "web/wp-content/themes/{$name}/": [ 94 | "type:wordpress-theme" 95 | ], 96 | "web/wp-content/mu-plugins/{$name}/": [ 97 | "type:wordpress-muplugin" 98 | ], 99 | "web/wp-content/{$name}/": [ 100 | "type:wordpress-dropin" 101 | ] 102 | }, 103 | "wordpress-install-dir": "web/wp/" 104 | }, 105 | "minimum-stability": "dev", 106 | "prefer-stable": true 107 | } 108 | -------------------------------------------------------------------------------- /config/scaffold/web/.htaccess: -------------------------------------------------------------------------------- 1 | # BEGIN WordPress 2 | # The directives (lines) between `BEGIN WordPress` and `END WordPress` are 3 | # dynamically generated, and should only be modified via WordPress filters. 4 | # Any changes to the directives between these markers will be overwritten. 5 | 6 | RewriteEngine On 7 | RewriteBase / 8 | RewriteRule ^index\.php$ - [L] 9 | RewriteCond %{REQUEST_FILENAME} !-f 10 | RewriteCond %{REQUEST_FILENAME} !-d 11 | RewriteRule . /index.php [L] 12 | 13 | # END WordPress 14 | -------------------------------------------------------------------------------- /config/scaffold/web/wp-config.php: -------------------------------------------------------------------------------- 1 | load(); 29 | 30 | // ** MySQL settings - You can get this info from your web host ** // 31 | /** The name of the database for WordPress */ 32 | define( 'DB_NAME', $_ENV['DB_DATABASE'] ); 33 | 34 | /** MySQL database username */ 35 | define( 'DB_USER', $_ENV['DB_USERNAME'] ); 36 | 37 | /** MySQL database password */ 38 | define( 'DB_PASSWORD', $_ENV['DB_PASSWORD'] ); 39 | 40 | /** MySQL hostname */ 41 | define( 'DB_HOST', $_ENV['DB_HOST'] ); 42 | 43 | /** Database Charset to use in creating database tables. */ 44 | define( 'DB_CHARSET', 'utf8' ); 45 | 46 | /** The Database Collate type. Do not change this if in doubt. */ 47 | define( 'DB_COLLATE', '' ); 48 | 49 | /** Limit the number of revisions store in the Database */ 50 | define( 'WP_POST_REVISIONS', $_ENV['WP_POST_REVISIONS'] ? (int) $_ENV['WP_POST_REVISIONS'] : 3 ); 51 | 52 | /**#@+ 53 | * Authentication Unique Keys and Salts. 54 | * 55 | * Change these to different unique phrases! 56 | * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service} 57 | * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again. 58 | * 59 | * @since 2.6.0 60 | */ 61 | 62 | define( 'AUTH_KEY', $_ENV['AUTH_KEY'] ); 63 | define( 'SECURE_AUTH_KEY', $_ENV['SECURE_AUTH_KEY'] ); 64 | define( 'LOGGED_IN_KEY', $_ENV['LOGGED_IN_KEY'] ); 65 | define( 'NONCE_KEY', $_ENV['NONCE_KEY'] ); 66 | define( 'AUTH_SALT', $_ENV['AUTH_SALT'] ); 67 | define( 'SECURE_AUTH_SALT', $_ENV['SECURE_AUTH_SALT'] ); 68 | define( 'LOGGED_IN_SALT', $_ENV['LOGGED_IN_SALT'] ); 69 | define( 'NONCE_SALT', $_ENV['NONCE_SALT'] ); 70 | 71 | /** 72 | * WordPress Database Table prefix. 73 | * 74 | * You can have multiple installations in one database if you give each a unique 75 | * prefix. Only numbers, letters, and underscores please! 76 | */ 77 | $table_prefix = $_ENV['DB_PREFIX']; 78 | 79 | /** 80 | * For developers: WordPress debugging mode. 81 | * 82 | * Change this to true to enable the display of notices during development. 83 | * It is strongly recommended that plugin and theme developers use WP_DEBUG 84 | * in their development environments. 85 | * 86 | * For information on other constants that can be used for debugging, 87 | * visit the Codex. 88 | * 89 | * @link https://codex.wordpress.org/Debugging_in_WordPress 90 | */ 91 | define( 'WP_DEBUG', 'true' === $_ENV['APP_DEBUG'] ? true : false ); 92 | define( 'WP_DEBUG_DISPLAY', 'true' === $_ENV['APP_DEBUG'] ? true : false ); 93 | 94 | if ( 'local' !== $_ENV['APP_ENV'] ) { 95 | define( 'AUTOMATIC_UPDATER_DISABLED', true ); 96 | define( 'DISALLOW_FILE_EDIT', true ); 97 | define( 'DISALLOW_FILE_MODS', true ); 98 | } 99 | 100 | /* That is all, stop editing! Happy blogging. */ 101 | 102 | /** Absolute path to the WordPress directory. */ 103 | if ( ! defined( 'ABSPATH' ) ) { 104 | define( 'ABSPATH', dirname( __FILE__ ) . '/wp' ); 105 | } 106 | 107 | /** Automatically set paths */ 108 | define( 'WP_HOME', ( 'true' === $_ENV['APP_SSL'] ? 'https://' : 'http://' ) . $_ENV['APP_HOST'] ); 109 | define( 'WP_SITEURL', WP_HOME . '/wp' ); 110 | 111 | /** Configure directory paths if WP core is in a different directory */ 112 | define( 'WP_CONTENT_URL', WP_HOME . '/wp-content' ); 113 | define( 'WP_CONTENT_DIR', realpath( ABSPATH . '../wp-content/' ) ); 114 | 115 | /* WP Rocket config */ 116 | define( 'WP_ROCKET_EMAIL', $_ENV['WP_ROCKET_EMAIL'] ); 117 | define( 'WP_ROCKET_KEY', $_ENV['WP_ROCKET_KEY'] ); 118 | define( 'WP_CACHE', 'true' === $_ENV['WP_CACHE'] ); 119 | 120 | /* Set default theme */ 121 | define( 'WP_DEFAULT_THEME', 'studiometa' ); 122 | 123 | /** 124 | * Allow WordPress to detect HTTPS when used behind a reverse proxy or a load balancer 125 | * @see https://codex.wordpress.org/Function_Reference/is_ssl#Notes 126 | */ 127 | if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] ) { 128 | $_SERVER['HTTPS'] = 'on'; 129 | } elseif ( isset( $_SERVER['HTTP_CF_VISITOR'] ) ) { 130 | try { 131 | $visitor = json_decode( $_SERVER['HTTP_CF_VISITOR'] ); 132 | if ( 'https' === $visitor->scheme ) { 133 | $_SERVER['HTTPS'] = 'on'; 134 | } 135 | } catch (\Exception $error) {} 136 | } 137 | 138 | /** Sets up WordPress vars and included files. */ 139 | require_once ABSPATH . 'wp-settings.php'; 140 | -------------------------------------------------------------------------------- /data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/data/.gitkeep -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["web/wp-content/themes/studiometa/src/js/**/*.js"], 3 | "compilerOptions": { 4 | "target": "es2015", 5 | "module": "esnext", 6 | "noEmit": true, 7 | "checkJs": true, 8 | "strict": false, 9 | "noImplicitThis": true, 10 | "esModuleInterop": true, 11 | "lib": ["esnext", "dom"], 12 | "moduleResolution": "bundler" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /meta.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@studiometa/webpack-config'; 2 | import { 3 | tailwindcss, 4 | eslint, 5 | stylelint, 6 | withContentHash, 7 | } from '@studiometa/webpack-config/presets'; 8 | 9 | // Paths must be relative to the package.json root 10 | export default defineConfig({ 11 | presets: [tailwindcss(), eslint(), stylelint(), withContentHash()], 12 | src: [ 13 | './web/wp-content/themes/studiometa/src/js/app.js', 14 | './web/wp-content/themes/studiometa/src/css/**/[!_]*.scss', 15 | ], 16 | dist: './web/wp-content/themes/studiometa/dist/', 17 | public: '/wp-content/themes/studiometa/dist/', 18 | watch: ['./web/wp-content/themes/studiometa/templates/**/*.twig'], 19 | }); 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@studiometa/wordpress-project", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "meta dev", 6 | "watch": "meta watch", 7 | "build": "meta build", 8 | "lint": "npm run lint:scripts && npm run lint:styles && npm run lint:templates", 9 | "lint:scripts": "eslint web/wp-content/themes/studiometa/src/js --ext=.js,.vue", 10 | "lint:styles": "stylelint 'web/wp-content/themes/studiometa/src/**/*.(scss|vue)'", 11 | "lint:templates": "prettier -c web/wp-content/themes/studiometa/templates/**/*.twig", 12 | "fix": "npm run fix:scripts && npm run fix:styles && npm run fix:templates", 13 | "fix:scripts": "npm run lint:scripts -- --fix", 14 | "fix:styles": "npm run lint:styles -- --fix", 15 | "fix:templates": "npm run lint:templates -- --write" 16 | }, 17 | "author": "Studio Meta (https://www.studiometa.fr)", 18 | "license": "MIT", 19 | "devDependencies": { 20 | "@studiometa/browserslist-config": "^1.0.1", 21 | "@studiometa/eslint-config": "^3.1.1", 22 | "@studiometa/prettier-config": "^2.1.1", 23 | "@studiometa/prettier-formatter-gitlab": "^1.1.2", 24 | "@studiometa/stylelint-config": "^3.0.0", 25 | "@studiometa/tailwind-config": "^2.0.2", 26 | "@studiometa/webpack-config": "^4.2.1", 27 | "eslint": "^8.38.0", 28 | "eslint-formatter-gitlab": "^3.0.0", 29 | "postcss": "^8.4.22", 30 | "prettier": "^2.8.7", 31 | "prettier-plugin-twig-melody": "^0.4.6", 32 | "stylelint": "^14.16.1", 33 | "stylelint-formatter-gitlab": "^1.0.2", 34 | "tailwindcss": "^3.3.1" 35 | }, 36 | "dependencies": { 37 | "@studiometa/js-toolkit": "^2.10.2", 38 | "@studiometa/ui": "^0.2.31" 39 | }, 40 | "browserslist": [ 41 | "extends @studiometa/browserslist-config" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /phpcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ./web/wp-content/themes/studiometa/ 5 | ./web/wp-content/mu-plugins/studiometa-plugin-disabler/ 6 | 7 | 8 | 9 | 10 | /data/ 11 | 12 | 13 | LocalValetDriver.php 14 | 15 | 16 | /vendor/ 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | /app/ 36 | /studiometa-plugin-disabler/studiometa-plugin-disabler.php 37 | 38 | 39 | 40 | 41 | /app/ 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | #$ composer update --optimize-autoloader 2 | #$ vendor/bin/phpstan analyze 3 | 4 | includes: 5 | # @see https://github.com/phpstan/phpstan-src/blob/master/conf/bleedingEdge.neon 6 | - phar://phpstan.phar/conf/bleedingEdge.neon 7 | # Include this extension 8 | - vendor/szepeviktor/phpstan-wordpress/extension.neon 9 | parameters: 10 | level: max 11 | cache: 12 | nodesByStringCountMax: 512 13 | inferPrivatePropertyTypeFromConstructor: true 14 | checkMissingIterableValueType: false 15 | reportUnmatchedIgnoredErrors: false 16 | checkGenericClassInNonGenericObjectType: false 17 | # bootstrapFiles: 18 | # # Missing constants, function and class stubs 19 | # - %currentWorkingDirectory%/tests/phpstan/bootstrap.php 20 | # scanFiles: 21 | # # Plugin stubs 22 | # - %currentWorkingDirectory%/tests/phpstan/PLUGIN-stubs.php 23 | # # Procedural code 24 | # - %currentWorkingDirectory%/myplugin-functions.php 25 | # autoload_directories: 26 | # - %currentWorkingDirectory%/inc/ 27 | scanDirectories: 28 | - ./web/wp-content/plugins/ 29 | paths: 30 | - ./web/wp-content/themes/studiometa/ 31 | - ./web/wp-content/mu-plugins/studiometa-plugin-disabler/ 32 | # - ./web/wp-content/mu-plugins/studiometa-… 33 | # - ./web/wp-content/plugins/studiometa-… 34 | # - ./web/wp-content/plugins/studiometa-… 35 | # excludes_analyse: 36 | # - %currentWorkingDirectory%/inc/views/ 37 | ignoreErrors: 38 | # Uses func_get_args() 39 | # - '#^Function apply_filters(_ref_array)? invoked with [34567] parameters, 2 required\.$#' 40 | # Fixed in WordPress 5.3 41 | #- '#^Function do_action(_ref_array)? invoked with [3456] parameters, 1-2 required\.$#' 42 | #- '#^Function current_user_can invoked with 2 parameters, 1 required\.$#' 43 | #- '#^Function add_query_arg invoked with [123] parameters?, 0 required\.$#' 44 | #- '#^Function wp_sprintf invoked with [23456] parameters, 1 required\.$#' 45 | #- '#^Function add_post_type_support invoked with [345] parameters, 2 required\.$#' 46 | #- '#^Function ((get|add)_theme_support|current_theme_supports) invoked with [2345] parameters, 1 required\.$#' 47 | # https://core.trac.wordpress.org/ticket/43304 48 | # - '/^Parameter #2 \$deprecated of function load_plugin_textdomain expects string, false given\.$/' 49 | # WP-CLI accepts a class as callable 50 | # - '/^Parameter #2 \$callable of static method WP_CLI::add_command\(\) expects callable\(\): mixed, \S+ given\.$/' 51 | # Please consider commenting ignores: issue URL or reason for ignoring 52 | - message: '#^Error(.+)thrown while looking(\s+)?for class Site\.#' 53 | path: web/wp-content/themes/studiometa/functions.php 54 | -------------------------------------------------------------------------------- /scripts/create-project.php: -------------------------------------------------------------------------------- 1 | sprintf( " \"name\": \"%s\",", $name ), 19 | 2 => " \"version\": \"0.0.0\",", 20 | ] 21 | ); 22 | 23 | updateFile( 24 | '.ddev/config.yaml', 25 | [ 26 | 0 => sprintf( 'name: %s', $name ), 27 | ] 28 | ); 29 | 30 | updateFile( 31 | '.gitlab-ci.yml', 32 | array( 33 | 3 => sprintf( ' DDEV_PROJECT_NAME: %s', $short_name ), 34 | ) 35 | ); 36 | 37 | updateFile( 38 | 'README.md', 39 | [ 40 | 0 => sprintf( "# %s", $name ), 41 | 7 => sprintf( 'git clone git@gitlab.com:studiometa/%s.git', $name ), 42 | ] 43 | ); 44 | 45 | runCommands( 46 | 'Removing unwanted files', 47 | [ 48 | 'rm -rf .github', 49 | ] 50 | ); 51 | 52 | runCommands( 53 | 'Initialize Git repository', 54 | [ 55 | 'git init', 56 | 'git branch -m master', 57 | 'git add .', 58 | 'git commit -m "Premier commit"', 59 | 'git checkout -b develop', 60 | ] 61 | ); 62 | 63 | runCommands( 64 | 'Install WordPress', 65 | [ 66 | 'cp .env.example .env', 67 | ] 68 | ); 69 | 70 | $salts = getSalts(); 71 | updateFile( 72 | '.env', 73 | [ 74 | 1 => 'APP_ENV=local', 75 | 2 => 'APP_DEBUG=true', 76 | 3 => 'APP_SSL=true', 77 | 9 => sprintf( 'DB_PREFIX=%s_', randomChars( 3 ) . randomNumber( 2 ) ), 78 | 15 => sprintf( 'AUTH_KEY="%s"', $salts['AUTH_KEY'] ), 79 | 16 => sprintf( 'SECURE_AUTH_KEY="%s"', $salts['SECURE_AUTH_KEY'] ), 80 | 17 => sprintf( 'LOGGED_IN_KEY="%s"', $salts['LOGGED_IN_KEY'] ), 81 | 18 => sprintf( 'NONCE_KEY="%s"', $salts['NONCE_KEY'] ), 82 | 19 => sprintf( 'AUTH_SALT="%s"', $salts['AUTH_SALT'] ), 83 | 20 => sprintf( 'SECURE_AUTH_SALT="%s"', $salts['SECURE_AUTH_SALT'] ), 84 | 21 => sprintf( 'LOGGED_IN_SALT="%s"', $salts['LOGGED_IN_SALT'] ), 85 | 22 => sprintf( 'NONCE_SALT="%s"', $salts['NONCE_SALT'] ), 86 | ] 87 | ); 88 | 89 | // @todo install wordpress 90 | // @todo dump first DB and add it to Git LFS 91 | // @todo delete self to avoid re-running this file 92 | 93 | echo PHP_EOL; 94 | -------------------------------------------------------------------------------- /scripts/functions/autoload.php: -------------------------------------------------------------------------------- 1 | execute() ) { 11 | $output = $command->getOutput(); 12 | $lines = explode( "\n", $output ); 13 | $salts = []; 14 | 15 | foreach ($lines as $line) { 16 | $matches = []; 17 | preg_match( "/define\('([A-z]+)',\s+'(.+)'\);/", $line, $matches ); 18 | $salts[$matches[1]] = $matches[2]; 19 | } 20 | 21 | return $salts; 22 | } else { 23 | throw $command->getError(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /scripts/functions/random.php: -------------------------------------------------------------------------------- 1 | execute() ) { 14 | $output = $cmd->getOutput(); 15 | 16 | if ( ! empty( $output ) ) 17 | echo "\n$output"; 18 | } else { 19 | echo $cmd->getError(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /scripts/functions/update-file.php: -------------------------------------------------------------------------------- 1 | $value ) { 23 | if ( ! empty( $value) ) { 24 | $file[$index] = $value . "\n"; 25 | } 26 | } 27 | 28 | // Remove lines last to avoid index errors 29 | foreach ( $newLines as $index => $value ) { 30 | if ( empty( $value) ) { 31 | unset( $file[$index] ); 32 | } 33 | } 34 | 35 | writeFile( $path, $file ); 36 | } 37 | -------------------------------------------------------------------------------- /scripts/get-wp-salts.php: -------------------------------------------------------------------------------- 1 | $value ) { 10 | echo "\n$name=$value"; 11 | } 12 | 13 | echo PHP_EOL; 14 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TailwindCSS Configuration File 3 | * 4 | * @see https://tailwindcss.com/docs/configuration 5 | * @default https://github.com/studiometa/tailwind-config/blob/develop/src/index.js 6 | */ 7 | module.exports = { 8 | presets: [require('tailwindcss/defaultConfig'), require('@studiometa/tailwind-config').config], 9 | // Extends the default Studio Meta Tailwind configuration here... 10 | // plugins: [...], 11 | // theme: {...}, 12 | // Learn more on https://tailwindcss.com/docs/controlling-file-size/#removing-unused-css 13 | content: [ 14 | './web/wp-content/themes/studiometa/src/js/**/*.js', 15 | './web/wp-content/themes/studiometa/src/js/**/*.vue', 16 | './web/wp-content/themes/studiometa/templates/**/*.twig', 17 | './vendor/studiometa/ui/package/ui/**/*.twig', 18 | './vendor/studiometa/ui/package/ui/**/*.js', 19 | 'tailwind.safelist.txt', 20 | ], 21 | }; 22 | -------------------------------------------------------------------------------- /tailwind.safelist.txt: -------------------------------------------------------------------------------- 1 | inset-0 -------------------------------------------------------------------------------- /web/index.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2021 Studio Meta 10 | * @license https://opensource.org/licenses/MIT 11 | * @version 1.0.0 12 | */ 13 | 14 | /** 15 | * DisablePlugins class. 16 | */ 17 | class DisablePlugins { 18 | /** 19 | * Instance. 20 | * 21 | * @var object 22 | */ 23 | public static $instance; 24 | 25 | /** 26 | * Disabled plugins. 27 | * 28 | * @var string[] 29 | */ 30 | private $disabled = array(); 31 | 32 | /** 33 | * Sets up the options filter, and optionally handles an array of plugins to disable 34 | * 35 | * @param string[] $disables Optional array of plugin filenames to disable. 36 | */ 37 | public function __construct( array $disables = null ) { 38 | /** 39 | * Handle what was passed in 40 | */ 41 | if ( is_array( $disables ) ) { 42 | foreach ( $disables as $disable ) { 43 | $this->disable( $disable ); 44 | } 45 | } 46 | 47 | /** 48 | * Add the filters 49 | */ 50 | add_filter( 'option_active_plugins', array( $this, 'do_disabling' ) ); 51 | add_filter( 'site_option_active_sitewide_plugins', array( $this, 'do_network_disabling' ) ); 52 | 53 | /** 54 | * Allow other plugins to access this instance 55 | */ 56 | self::$instance = $this; 57 | } 58 | 59 | /** 60 | * Adds a filename to the list of plugins to disable 61 | * 62 | * @param string $file File to disable. 63 | * 64 | * @return void 65 | */ 66 | public function disable( $file ) { 67 | $this->disabled[] = $file; 68 | } 69 | 70 | /** 71 | * Hooks in to the option_active_plugins filter and does the disabling 72 | * 73 | * @param string[] $plugins WP-provided list of plugin filenames. 74 | * 75 | * @return string[] The filtered array of plugin filenames 76 | */ 77 | public function do_disabling( $plugins ) { 78 | if ( count( $this->disabled ) ) { 79 | foreach ( (array) $this->disabled as $plugin ) { 80 | $key = array_search( $plugin, $plugins, true ); 81 | if ( false !== $key ) { 82 | unset( $plugins[ $key ] ); 83 | } 84 | } 85 | } 86 | 87 | return $plugins; 88 | } 89 | 90 | /** 91 | * Hooks in to the site_option_active_sitewide_plugins filter and does the disabling 92 | * 93 | * @param string[] $plugins Plugins. 94 | * 95 | * @return string[] 96 | */ 97 | public function do_network_disabling( $plugins ) { 98 | if ( count( $this->disabled ) ) { 99 | foreach ( (array) $this->disabled as $plugin ) { 100 | if ( isset( $plugins[ $plugin ] ) ) { 101 | unset( $plugins[ $plugin ] ); 102 | } 103 | } 104 | } 105 | 106 | return $plugins; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /web/wp-content/mu-plugins/studiometa-plugin-disabler/studiometa-plugin-disabler.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2021 Studio Meta 12 | * @license https://opensource.org/licenses/MIT 13 | * @version 1.0.0 14 | */ 15 | 16 | /** 17 | * StudiometaPluginDisabler class. 18 | */ 19 | class StudiometaPluginDisabler { 20 | /** 21 | * Disable plugins. 22 | * 23 | * @return void 24 | */ 25 | public static function init() { 26 | if ( ! defined( 'WP_ENV' ) ) { 27 | return; 28 | } 29 | 30 | $plugins_to_disable_raw = getenv( 'DISABLE_PLUGINS_' . strtoupper( WP_ENV ) ); 31 | 32 | if ( ! $plugins_to_disable_raw ) { 33 | return; 34 | } 35 | 36 | $plugins_to_disable = array_filter( explode( ',', $plugins_to_disable_raw ) ); 37 | 38 | if ( empty( $plugins_to_disable ) ) { 39 | return; 40 | } 41 | 42 | new DisablePlugins( $plugins_to_disable ); 43 | } 44 | } 45 | 46 | require_once __DIR__ . '/includes/class-disableplugins.php'; 47 | 48 | StudiometaPluginDisabler::init(); 49 | -------------------------------------------------------------------------------- /web/wp-content/mu-plugins/studiometa-plugin-disabler/uninstall.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2021 Studio Meta 8 | * @license https://opensource.org/licenses/MIT 9 | * @version 1.0.0 10 | */ 11 | 12 | if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) { 13 | exit; 14 | } 15 | -------------------------------------------------------------------------------- /web/wp-content/plugins/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/plugins/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/404.php: -------------------------------------------------------------------------------- 1 | addText( 'title', array( 'label' => __( 'Titre du block', 'studiometa' ) ) ) 26 | ->addRepeater( 'list' ) 27 | ->addText( 'title', array( 'label' => __( 'Titre', 'studiometa' ) ) ) 28 | ->addWysiwyg( 'content', array( 'label' => __( 'Contenu', 'studiometa' ) ) ) 29 | ->endRepeater(); 30 | 31 | return $accordion_block; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Blocks/BlockInterface.php: -------------------------------------------------------------------------------- 1 | addImage( 25 | 'image', 26 | array( 27 | 'label' => __( 'Image', 'studiometa' ), 28 | 'instructions' => 'Format HD à privilégier', 29 | ) 30 | ); 31 | 32 | return $image_block; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Blocks/ImageText.php: -------------------------------------------------------------------------------- 1 | addImage( 'image', array( 'label' => __( 'Image', 'studiometa' ) ) ) 25 | ->addWysiwyg( 'content', array( 'label' => __( 'Contenu', 'studiometa' ) ) ) 26 | ->addLink( 27 | 'cta', 28 | array( 29 | 'label' => __( 'Bouton CTA', 'studiometa' ), 30 | 'instructions' => __( 'Ajoute un CTA, si non renseigné il ne sera pas visible', 'studiometa' ), 31 | 'return_format' => 'array', 32 | ), 33 | ) 34 | ->addRadio( 35 | 'text_position', 36 | array( 37 | 'label' => __( 'Position du bloc texte', 'studiometa' ), 38 | 'default_value' => 'left', 39 | 'choices' => array( 40 | 'left' => __( 'Gauche', 'studiometa' ), 41 | 'right' => __( 'Droite', 'studiometa' ), 42 | ), 43 | ) 44 | ); 45 | 46 | return $push_block; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Blocks/README.md: -------------------------------------------------------------------------------- 1 | # Blocks 2 | 3 | Some default blocks we used in our projects -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Blocks/Text.php: -------------------------------------------------------------------------------- 1 | addWysiwyg( 25 | 'content', 26 | array( 27 | 'label' => __( 'Contenu', 'studiometa' ), 28 | 'toolbar' => 'full', 29 | ) 30 | ); 31 | return $wysiwyg_block; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Blocks/Video.php: -------------------------------------------------------------------------------- 1 | addText( 'title', array( 'label' => __( 'Titre de la vidéo', 'studiometa' ) ) ) 25 | ->addFile( 26 | 'video', 27 | array( 28 | 'label' => __( 'Vidéo', 'studiometa' ), 29 | 'instructions' => __( 'Format MP4 à privilégier', 'studiometa' ), 30 | ) 31 | ) 32 | ->addImage( 33 | 'video_cover', 34 | array( 35 | 'label' => __( 'Image de couverture', 'studiometa' ), 36 | ) 37 | ) 38 | ->addText( 39 | 'video_legend', 40 | array( 41 | 'label' => __( 'Légende vidéo', 'studiometa' ), 42 | 'instructions' => __( 'Caché si non renseigné', 'studiometa' ), 43 | ) 44 | ); 45 | 46 | return $video_block; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Managers/ACFManager.php: -------------------------------------------------------------------------------- 1 | 'Page builder' ) ); 38 | // @phpstan-ignore-next-line 39 | $builder_group->addFlexibleContent( 'builder', array( 'button_label' => __( 'Ajouter section', 'studiometa' ) ) ) 40 | ->addLayout( Video::get_block() ) 41 | ->addLayout( ImageText::get_block() ) 42 | ->addLayout( Text::get_block() ) 43 | ->addLayout( Image::get_block() ) 44 | ->addLayout( Accordion::get_block() ) 45 | ->setLocation( 'page_template', '==', 'page-template-builder.php' ); 46 | acf_add_local_field_group( $builder_group->build() ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Managers/CustomPostTypesManager.php: -------------------------------------------------------------------------------- 1 | set_labels( 'Sample', 'Samples' ) 36 | ->register(); 37 | } 38 | 39 | /** 40 | * Set the class map for Timber instantiation of posts. 41 | * 42 | * @param string $post_class The default post class. 43 | * @return string[] The project's class map. 44 | */ 45 | public function set_timber_classmap( string $post_class ): array { 46 | $post_types = get_post_types(); 47 | $class_map = array(); 48 | $exclude_post_types = array( 49 | 'acf-field', 50 | 'acf-field-group', 51 | 'attachment', 52 | 'custom_css', 53 | 'customize_changeset', 54 | 'nav_menu_item', 55 | 'oembed_cache', 56 | 'revision', 57 | 'user_request', 58 | 'wp_block', 59 | 'wp_template', 60 | 'wp_navigation', 61 | 'wp_template_part', 62 | 'wp_global_styles', 63 | ); 64 | 65 | foreach ( $post_types as $key => $post_type ) { 66 | // Do not change the class_map of default WordPress post_types. 67 | if ( in_array( $post_type, $exclude_post_types, true ) ) { 68 | continue; 69 | } 70 | 71 | $class_map[ $key ] = '\Studiometa\Models\\' . ucfirst( $key ); 72 | } 73 | 74 | return $class_map; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Managers/README.md: -------------------------------------------------------------------------------- 1 | # Managers 2 | 3 | @todo small section about what is a manager 4 | 5 | ## ThemeManager 6 | The main manager, that will init all the other Managers 7 | Bootstraps Theme related functions: 8 | - Add data to global twig context 9 | - Add twig extensions 10 | - Add menus 11 | - Add theme support 12 | - ... 13 | 14 | ## AssetsManager 15 | Bootstraps Studiometa\WP\Assets to handle enqueing styles and scripts 16 | 17 | ## TwigManager 18 | Add Extentions and Functions to Twig 19 | 20 | ## WordPressManager 21 | Add functionnality to WordPress 22 | 23 | ## CustomPostTypesManager 24 | Register custom post types 25 | 26 | ## TaxonomiesManager 27 | Register custom taxonomies 28 | 29 | ## ACFManager 30 | Bootsrap ACF related features 31 | - Register ACF field groups 32 | - Register ACF Options pages 33 | - ... 34 | 35 | ## Add a new manager 36 | - Add it to the managers array in `functions.php` 37 | @todo small section about when to create a new manager 38 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Managers/TaxonomiesManager.php: -------------------------------------------------------------------------------- 1 | set_post_types( 'sample' ) 35 | ->set_labels( 'Sample Category', 'Sample Categories' ) 36 | ->register(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Managers/ThemeManager.php: -------------------------------------------------------------------------------- 1 | 'Navigation Header Menu', 77 | 'footer_menu' => 'Navigation Footer Menu', 78 | ) 79 | ); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Managers/TinyMCEManager.php: -------------------------------------------------------------------------------- 1 | assets_manager = $assets_manager; 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | public function run() { 35 | add_filter( 'tiny_mce_before_init', array( $this, 'set_editor_config' ) ); 36 | add_action( 'admin_enqueue_scripts', array( $this, 'add_editor_stylesheet' ), 11 ); 37 | add_filter( 'mce_buttons', array( $this, 'add_editor_buttons' ) ); 38 | } 39 | 40 | /** 41 | * Add a buttons to the TinyMCE editor 42 | * 43 | * @param mixed[] $buttons Buttons list. 44 | * @return mixed[] 45 | */ 46 | public function add_editor_buttons( $buttons ) { 47 | array_unshift( $buttons, 'styleselect' ); 48 | 49 | return $buttons; 50 | } 51 | 52 | /** 53 | * Set TinyMCE Editor config 54 | * - add custom style formats dropdown 55 | * - add custom colors 56 | * 57 | * @param mixed[] $config Configuration. 58 | * @return mixed[] 59 | */ 60 | public function set_editor_config( $config ) { 61 | $style_formats = array( 62 | array( 63 | 'title' => __( 'Titre h1' ), 64 | 'selector' => 'p, h1, h2, h3, h4, h5, h6', 65 | 'classes' => 'type-h1', 66 | ), 67 | array( 68 | 'title' => __( 'Titre h2' ), 69 | 'selector' => 'p, h1, h2, h3, h4, h5, h6', 70 | 'classes' => 'type-h2', 71 | ), 72 | array( 73 | 'title' => __( 'Titre h3' ), 74 | 'selector' => 'p, h1, h2, h3, h4, h5, h6', 75 | 'classes' => 'type-h3', 76 | ), 77 | array( 78 | 'title' => __( 'Titre h4' ), 79 | 'selector' => 'p, h1, h2, h3, h4, h5, h6', 80 | 'classes' => 'type-h4', 81 | ), 82 | ); 83 | 84 | // Add custom style_formats to TinyMCE. 85 | $config['style_formats'] = wp_json_encode( $style_formats ); 86 | 87 | return $config; 88 | } 89 | 90 | /** 91 | * Load a custom stylesheet for TinyMCE wysiwyg editor 92 | * 93 | * @return void 94 | */ 95 | public function add_editor_stylesheet() { 96 | $stylesheet = $this->assets_manager->webpack_manifest->asset( 'css/admin/editor-style.css' ); 97 | 98 | if ( $stylesheet ) { 99 | add_editor_style( $stylesheet ); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Managers/TwigManager.php: -------------------------------------------------------------------------------- 1 | getLoader(); 40 | $twig->addExtension( 41 | new Extension( 42 | $loader, 43 | get_template_directory() . '/templates', 44 | get_template_directory() . '/static/svg', 45 | ) 46 | ); 47 | 48 | return $twig; 49 | } 50 | 51 | /** 52 | * Adds template_from_string to Twig. 53 | * 54 | * @link https://twig.symfony.com/doc/2.x/functions/template_from_string.html 55 | * @param \Twig\Environment $twig The Twig environment. 56 | * @return \Twig\Environment 57 | */ 58 | public function add_twig_template_from_string( \Twig\Environment $twig ) { 59 | $twig->addExtension( new \Twig\Extension\StringLoaderExtension() ); 60 | return $twig; 61 | } 62 | 63 | /** 64 | * Adds template_from_string to Twig. 65 | * 66 | * @link https://github.com/djboris88/twig-commented-include 67 | * @param \Twig\Environment $twig The Twig environment. 68 | * @return \Twig\Environment 69 | */ 70 | public function add_twig_template_include_comments( \Twig\Environment $twig ) { 71 | if ( getenv( 'APP_DEBUG' ) === 'false' ) { 72 | return $twig; 73 | } 74 | 75 | $twig->addExtension( new \Djboris88\Twig\Extension\CommentedIncludeExtension() ); 76 | return $twig; 77 | } 78 | 79 | /** 80 | * Add debug comments to Timber::render 81 | * 82 | * @param string $output HTML. 83 | * @param mixed[] $data Data. 84 | * @param string $file Name. 85 | * @return string 86 | */ 87 | public function add_twig_template_render_comments( $output, $data, $file ) { 88 | if ( getenv( 'APP_DEBUG' ) === 'false' ) { 89 | return $output; 90 | } 91 | 92 | return "\n\n" . $output . "\n\n"; 93 | } 94 | 95 | /** 96 | * Add an alias for the SVG folder. 97 | * 98 | * @example {{ source('@svg/icon.svg') }} 99 | * @param \Twig\Loader\FilesystemLoader $fs The loader to extend. 100 | * @return \Twig\Loader\FilesystemLoader 101 | */ 102 | public function add_svg_path( \Twig\Loader\FilesystemLoader $fs ) { 103 | $fs->addPath( get_template_directory() . '/static/svg', 'svg' ); 104 | return $fs; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Managers/WordPressManager.php: -------------------------------------------------------------------------------- 1 | '; 32 | echo "\n"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Models/Page.php: -------------------------------------------------------------------------------- 1 | $this->post_title, 29 | 'surtitle' => $this->meta( 'hero_surtitle' ), 30 | ); 31 | } 32 | } 33 | 34 | // single-posttype.php 35 | $post = new \Studiometa\Models\Posttype(); 36 | var_dump( $post->hero ); 37 | // Will return array( 'title' => '...', 'surtitle' => '...' ); 38 | ``` 39 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Repositories/PostRepository.php: -------------------------------------------------------------------------------- 1 | 100 ) { 43 | // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error 44 | trigger_error( __CLASS__ . ' ' . __FUNCTION__ . ' : $limit parameter should not be over 100 to avoid full sql table scans', E_USER_WARNING ); 45 | $limit = 100; 46 | } 47 | 48 | // Note the + symbol. See https://developer.wordpress.org/reference/classes/wp_query/#category-parameters. 49 | if ( is_array( $slug ) ) { 50 | $slug = implode( '+', $slug ); 51 | } 52 | 53 | $params = array( 54 | 'posts_per_page' => (int) $limit, 55 | 'category_name' => $slug, 56 | 'post_type' => self::POST_TYPES, 57 | 'post_status' => 'publish', 58 | 'orderby' => 'date', 59 | 'order' => 'DESC', 60 | ); 61 | 62 | if ( ! empty( $exclude ) ) { 63 | $params['post__not_in'] = $exclude; 64 | } 65 | 66 | if ( (int) $paged > 0 ) { 67 | $params['paged'] = $paged; 68 | } 69 | 70 | return $this->query( $params ); 71 | } 72 | 73 | /** 74 | * Returns a chronological list of latest posts across all *public* post types. 75 | * This acts as a "firehose" of new content so to speak. 76 | * 77 | * @param integer $limit Number of posts to return. 78 | * @param mixed[] $exclude IDs of posts to exclude. 79 | * @param integer $paged Enable pagination. 80 | * 81 | * @return Repository 82 | */ 83 | public function latest_posts( $limit = 10, array $exclude = array(), $paged = 0 ) { 84 | 85 | // Set sane defaults so we don't do full table scans. 86 | if ( $limit <= 0 || $limit > 100 ) { 87 | // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error 88 | trigger_error( __CLASS__ . ' ' . __FUNCTION__ . ' : $limit parameter should not be over 100 to avoid full sql table scans', E_USER_WARNING ); 89 | $limit = 100; 90 | } 91 | 92 | $params = array( 93 | 'posts_per_page' => (int) $limit, 94 | 'post_type' => self::POST_TYPES, 95 | 'post_status' => 'publish', 96 | 'orderby' => 'date', 97 | 'order' => 'DESC', 98 | ); 99 | 100 | if ( count( $exclude ) > 0 ) { 101 | $params['post__not_in'] = $exclude; 102 | } 103 | 104 | if ( (int) $paged > 0 ) { 105 | $params['paged'] = $paged; 106 | } 107 | 108 | return $this->query( $params ); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Repositories/README.md: -------------------------------------------------------------------------------- 1 | # Repositories 2 | 3 | - Use Repositories to add query related logic. 4 | - All Repositories should extend the base `Repository` class. 5 | - All Repositories query functions has to `return $this->query( $params );` because `$this->query` is adding cache to the request by default. 6 | 7 | 8 | ## Example 9 | ```php 10 | use Studiometa\Repositories\PostRepository; 11 | 12 | // Get the 10 latest posts 13 | $post_repo = new PostRepository(); 14 | $context['posts'] = $post_repo->latest_posts(10)->get(); 15 | 16 | // Full list of available arguments 17 | $context['posts'] = $post_repo->latest_posts($limit, $post_types, $exclude_posts, $paged)->get(); 18 | ``` 19 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Repositories/Repository.php: -------------------------------------------------------------------------------- 1 | result_set; 27 | } 28 | 29 | /** 30 | * Returns the first item in a collection. Returns null if there are 0 items in 31 | * the collection. 32 | * 33 | * @return mixed 34 | */ 35 | public function first() { 36 | $local_array = $this->get(); 37 | return isset( $local_array[0] ) ? $local_array[0] : null; 38 | } 39 | 40 | /** 41 | * Runs a query. 42 | * 43 | * @param mixed[] $params Query params. 44 | * 45 | * @return Repository 46 | */ 47 | protected function query( array $params ) { 48 | // Clear old result sets. 49 | $this->reset(); 50 | 51 | $cache_key = __FUNCTION__ . md5( http_build_query( $params ) ); 52 | 53 | /** 54 | * Cached results. 55 | * 56 | * @var false|mixed[] 57 | */ 58 | $cached_results = wp_cache_get( $cache_key, __CLASS__ ); 59 | 60 | if ( false !== $cached_results && count( $cached_results ) > 0 ) { 61 | // Use cached results. 62 | return $this->result_set( $cached_results ); 63 | } 64 | 65 | $results = $this->do_query( $params ); 66 | 67 | // Cache our results. 68 | if ( count( $results ) > 0 ) { 69 | wp_cache_set( $cache_key, $results, __CLASS__ ); 70 | } 71 | 72 | return $this->result_set( $results ); 73 | } 74 | 75 | /** 76 | * Function to implement when extendding the Repository. 77 | * 78 | * Define the query the Repository will run. 79 | * 80 | * @param mixed[] $params Query params. 81 | * @return mixed[] 82 | * 83 | * @example ./app/Repositories/PostRepository.php How to implement do_query(). 84 | */ 85 | abstract protected function do_query( $params ); 86 | 87 | /** 88 | * Clears the current result set. 89 | * 90 | * @return Repository 91 | */ 92 | protected function reset() { 93 | $this->result_set = array(); 94 | return $this; 95 | } 96 | 97 | /** 98 | * Returns current result set 99 | * 100 | * @param mixed[] $result_set Result set. 101 | * 102 | * @return Repository 103 | */ 104 | protected function result_set( $result_set ) { 105 | $this->result_set = $result_set; 106 | return $this; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Repositories/TermRepository.php: -------------------------------------------------------------------------------- 1 | $params Query params. 20 | * @return \Timber\Term[] 21 | */ 22 | public function do_query( $params ) { 23 | /** 24 | * Terms. 25 | * 26 | * @var \Timber\Term[] 27 | */ 28 | return TermGetter::get_terms( $params, array(), static::CLASS_TYPE ); 29 | } 30 | 31 | /** 32 | * Returns a list of top level terms 33 | * 34 | * @param string|string[] $taxonomy Slug. 35 | * @param mixed[] $exclude IDs of posts to exclude. 36 | * @param int $limit Number of maximum results. 37 | * 38 | * @return Repository 39 | */ 40 | public function top_level_terms( $taxonomy, $exclude = array(), $limit = 100 ) { 41 | // Set sane defaults so we don't do full table scans. 42 | if ( $limit <= 0 || $limit > 100 ) { 43 | // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error 44 | trigger_error( __CLASS__ . ' ' . __FUNCTION__ . ' : $limit parameter should not be over 100 to avoid full sql table scans', E_USER_WARNING ); 45 | $limit = 100; 46 | } 47 | 48 | $params = array( 49 | 'taxonomy' => $taxonomy, 50 | 'parent' => 0, // Only get top level taxonomies. 51 | 'limit' => $limit, 52 | ); 53 | 54 | if ( count( $exclude ) > 0 ) { 55 | $params['exclude'] = $exclude; 56 | } 57 | 58 | return $this->query( $params ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/app/Services/README.md: -------------------------------------------------------------------------------- 1 | # Services 2 | 3 | todo 4 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/archive.php: -------------------------------------------------------------------------------- 1 | latest_posts( 10 )->get(); 43 | 44 | Timber::render( $templates, $context ); 45 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/config/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/config/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/config/assets.yml: -------------------------------------------------------------------------------- 1 | # Assets management for WordPress 2 | # @see https://github.com/studiometa/wp-assets/tree/feature/v2#readme 3 | 4 | # Assets loaded on all templates 5 | all: 6 | entries: 7 | - css/app.scss 8 | - js/app.js 9 | 10 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/footer.php: -------------------------------------------------------------------------------- 1 |

Timber not activated. Make sure you activate the plugin in ' . esc_url( admin_url( 'plugins.php' ) ) . '

'; 32 | } 33 | ); 34 | 35 | if ( ! is_admin() ) { 36 | die( 'Timber not activated.' ); 37 | } 38 | } 39 | 40 | $timber = new Timber(); 41 | 42 | /** 43 | * Sets the directories (inside your theme) to find .twig files 44 | */ 45 | Timber::$dirname = array( 'templates' ); 46 | 47 | /** 48 | * By default, Timber does NOT autoescape values. Want to enable Twig's autoescape? 49 | * No prob! Just set this value to true 50 | */ 51 | Timber::$autoescape = true; 52 | 53 | add_action( 54 | 'after_setup_theme', 55 | function () { 56 | $assets_manager = new AssetsManager(); 57 | 58 | $managers = array( 59 | $assets_manager, 60 | new ThemeManager(), 61 | new WordPressManager(), 62 | new TwigManager(), 63 | new CleanupManager(), 64 | new CustomPostTypesManager(), 65 | new TaxonomiesManager(), 66 | new TinyMCEManager( $assets_manager ), 67 | new ACFManager(), 68 | ); 69 | 70 | ManagerFactory::init( $managers ); 71 | } 72 | ); 73 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/header.php: -------------------------------------------------------------------------------- 1 | latest_posts( 10 )->get(); 22 | $templates = array( 'pages/index.twig' ); 23 | 24 | if ( is_home() ) { 25 | array_unshift( $templates, 'pages/home.twig' ); 26 | } 27 | 28 | Timber::render( $templates, $context ); 29 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/page-template-builder.php: -------------------------------------------------------------------------------- 1 | meta( 'builder' ); 16 | 17 | Timber::render( array( 'pages/page-template-builder.twig' ), $context ); 18 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/page.php: -------------------------------------------------------------------------------- 1 | name() . '.twig', 'pages/page.twig' ), $context ); 32 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/search.php: -------------------------------------------------------------------------------- 1 | id ) ) { 20 | Timber::render( 'pages/single-password.twig', $context ); 21 | } else { 22 | Timber::render( array( 'pages/single-' . $timber_post->id . '.twig', 'pages/single-' . $timber_post->type() . '.twig', 'pages/single.twig' ), $context ); 23 | } 24 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/_config.scss: -------------------------------------------------------------------------------- 1 | /*============================================================================*\ 2 | Config SCSS 3 | \*============================================================================*/ 4 | 5 | /* Assets directories 6 | \*============================================================================*/ 7 | 8 | $img-dir: '/wp-content/themes/studiometa/static/img/'; 9 | $svg-dir: '/wp-content/themes/studiometa/static/svg/'; 10 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/admin/editor-style.scss: -------------------------------------------------------------------------------- 1 | /*------------------------------------* 2 | TinyMCE Editor style 3 | *------------------------------------*/ 4 | 5 | @import '../config'; 6 | @import 'tailwindcss/base'; 7 | @import 'tailwindcss/components'; 8 | @import 'tailwindcss/utilities'; 9 | 10 | // Main parent of the TinyMCE wysiwyg Editor. 11 | #tinymce { 12 | // Add nice padding. 13 | padding: 1.5rem !important; 14 | 15 | @apply text-base; 16 | 17 | h1 { 18 | @apply text-4xl; 19 | } 20 | 21 | h2 { 22 | @apply text-3xl; 23 | } 24 | 25 | h3 { 26 | @apply text-2xl; 27 | } 28 | 29 | h1, 30 | h2, 31 | h3, 32 | h4 { 33 | margin-bottom: theme('spacing.6'); 34 | } 35 | 36 | p, 37 | li { 38 | a { 39 | text-decoration: underline; 40 | transition: opacity 0.2s; 41 | 42 | &:hover { 43 | opacity: 0.75; 44 | } 45 | } 46 | } 47 | 48 | ul { 49 | li { 50 | position: relative; 51 | padding-left: theme('spacing.3'); 52 | } 53 | 54 | &::before { 55 | content: '•'; 56 | position: absolute; 57 | left: 0; 58 | color: currentColor; 59 | } 60 | } 61 | 62 | li + li { 63 | margin-top: theme('spacing.3'); 64 | } 65 | 66 | p, 67 | ul { 68 | + p, 69 | + ul { 70 | margin-top: theme('spacing.4'); 71 | } 72 | 73 | + h1, 74 | + h2, 75 | + h3, 76 | + h4 { 77 | margin-top: theme('spacing.10'); 78 | } 79 | } 80 | 81 | strong { 82 | font-weight: bold; 83 | } 84 | 85 | img { 86 | display: block; 87 | width: 100%; 88 | height: auto; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/app.scss: -------------------------------------------------------------------------------- 1 | /* Globals 2 | \*============================================================================*/ 3 | 4 | @import 'tailwindcss/base'; 5 | @import './base'; 6 | 7 | /* Components 8 | \*============================================================================*/ 9 | 10 | @import 'tailwindcss/components'; 11 | @import './atoms'; 12 | @import './molecules'; 13 | @import './organisms'; 14 | 15 | /* Utilities 16 | \*============================================================================*/ 17 | 18 | @import 'tailwindcss/utilities'; 19 | @import './utilities'; 20 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/atoms/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/src/css/atoms/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/atoms/_index.scss: -------------------------------------------------------------------------------- 1 | // @import './atom'; 2 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/base/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/src/css/base/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/base/_index.scss: -------------------------------------------------------------------------------- 1 | // @import './base'; 2 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/molecules/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/src/css/molecules/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/molecules/_index.scss: -------------------------------------------------------------------------------- 1 | // @import './molecule'; 2 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/organisms/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/src/css/organisms/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/organisms/_index.scss: -------------------------------------------------------------------------------- 1 | @import './blocks/wysiwyg'; 2 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/organisms/blocks/_wysiwyg.scss: -------------------------------------------------------------------------------- 1 | /*============================================================================*\ 2 | Default wysiwyg configuration 3 | Feel free to change all styles 4 | \*============================================================================*/ 5 | 6 | .wysiwyg { 7 | @apply text-base; 8 | 9 | h1 { 10 | @apply text-4xl; 11 | } 12 | 13 | h2 { 14 | @apply text-3xl; 15 | } 16 | 17 | h3 { 18 | @apply text-2xl; 19 | } 20 | 21 | h1, 22 | h2, 23 | h3, 24 | h4 { 25 | margin-bottom: theme('spacing.6'); 26 | } 27 | 28 | p, 29 | li { 30 | a { 31 | text-decoration: underline; 32 | transition: opacity 0.2s; 33 | 34 | &:hover { 35 | opacity: 0.75; 36 | } 37 | } 38 | } 39 | 40 | ul { 41 | li { 42 | position: relative; 43 | padding-left: theme('spacing.3'); 44 | 45 | &::before { 46 | content: '•'; 47 | position: absolute; 48 | left: 0; 49 | color: currentColor; 50 | } 51 | } 52 | } 53 | 54 | li + li { 55 | margin-top: theme('spacing.3'); 56 | } 57 | 58 | p, 59 | ul { 60 | + p, 61 | + ul { 62 | margin-top: theme('spacing.4'); 63 | } 64 | 65 | + h1, 66 | + h2, 67 | + h3, 68 | + h4 { 69 | margin-top: theme('spacing.10'); 70 | } 71 | } 72 | 73 | strong { 74 | font-weight: bold; 75 | } 76 | 77 | img { 78 | display: block; 79 | width: 100%; 80 | height: auto; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/utilities/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/src/css/utilities/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/css/utilities/_index.scss: -------------------------------------------------------------------------------- 1 | // @import './utility'; 2 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/js/app.js: -------------------------------------------------------------------------------- 1 | import { Base, createApp, importWhenVisible } from '@studiometa/js-toolkit'; 2 | import { Figure } from '@studiometa/ui'; 3 | import { isDev } from './config.js'; 4 | 5 | /** 6 | * Main App class. 7 | */ 8 | class App extends Base { 9 | /** 10 | * App config. 11 | * @returns {Object} 12 | */ 13 | static config = { 14 | log: isDev(), 15 | name: 'App', 16 | components: { 17 | Figure, 18 | Video: (app) => importWhenVisible(() => import('./molecules/Video.js'), 'Video', app), 19 | Accordion: (app) => 20 | importWhenVisible(() => import('./molecules/Accordion.js'), 'Accordion', app), 21 | }, 22 | }; 23 | 24 | /** 25 | * Log a nice message when app is ready. 26 | * 27 | * @returns {void} 28 | */ 29 | mounted() { 30 | this.$log('mounted 🎉'); 31 | } 32 | } 33 | 34 | export default createApp(App, document.body); 35 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/js/atoms/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/src/js/atoms/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/js/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Test if the current env is a dev env. 3 | * 4 | * @returns {boolean} 5 | */ 6 | export const isDev = () => !window.location.hostname.startsWith('www.'); 7 | 8 | export default { 9 | isDev, 10 | }; 11 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/js/molecules/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/src/js/molecules/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/js/molecules/Accordion.js: -------------------------------------------------------------------------------- 1 | import { Accordion as AccordionCore } from '@studiometa/ui'; 2 | 3 | /** 4 | * component 5 | */ 6 | export default class Accordion extends AccordionCore { 7 | /** 8 | * Component Configuration 9 | */ 10 | static config = { 11 | name: 'Accordion', 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/js/molecules/Component.js: -------------------------------------------------------------------------------- 1 | import { Base } from '@studiometa/js-toolkit'; 2 | 3 | /** 4 | * Homepage class. 5 | */ 6 | export default class Component extends Base { 7 | /** 8 | * Class cofnig 9 | * @type {Object} 10 | */ 11 | static config = { 12 | name: 'Component', 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/js/molecules/Video.js: -------------------------------------------------------------------------------- 1 | import { Base } from '@studiometa/js-toolkit'; 2 | 3 | /** 4 | * Homepage class. 5 | */ 6 | export default class Video extends Base { 7 | /** 8 | * Class config 9 | * @type {Object} 10 | */ 11 | static config = { 12 | name: 'Video', 13 | refs: ['play', 'videoPlayer', 'videoCover'], 14 | }; 15 | 16 | /** 17 | * Open child panel 18 | * @returns {void} 19 | */ 20 | onPlayClick() { 21 | this.playVideo(); 22 | } 23 | 24 | /** 25 | * Click on video cover 26 | * @returns {void} 27 | */ 28 | onVideoCoverClick() { 29 | this.playVideo(); 30 | } 31 | 32 | /** 33 | * Pause video when user pause video 34 | * @returns {void} 35 | */ 36 | onVideoPlayerPause() { 37 | this.pauseVideo(); 38 | } 39 | 40 | /** 41 | * Play video ! 42 | * @returns {void} 43 | */ 44 | playVideo() { 45 | this.$refs.videoCover.style.opacity = 0; 46 | this.$refs.videoCover.style.pointerEvents = 'none'; 47 | this.$refs.play.style.opacity = 0; 48 | this.$refs.play.style.pointerEvents = 'none'; 49 | this.$refs.videoPlayer.play(); 50 | } 51 | 52 | /** 53 | * Pause video ! 54 | * @returns {void} 55 | */ 56 | pauseVideo() { 57 | this.$refs.videoCover.style.opacity = 1; 58 | this.$refs.videoCover.style.pointerEvents = 'auto'; 59 | this.$refs.play.style.opacity = 1; 60 | this.$refs.play.style.pointerEvents = 'auto'; 61 | this.$refs.videoPlayer.pause(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/js/organisms/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/src/js/organisms/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/src/js/utils/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/src/js/utils/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/static/fonts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/static/fonts/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/static/img/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/static/img/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/static/svg/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/static/svg/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/static/svg/play.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/style.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Theme Name: <%= name %> 3 | * Description: <%= description %> 4 | * Author: Studio Meta (https://www.studiometa.fr) 5 | * Version : 1.0.0-beta.4 6 | */ 7 | 8 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/atoms/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/templates/atoms/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/layouts/base.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {{ function('wp_head') }} 14 | 15 | {% block head %} 16 | 17 | {% endblock %} 18 | 19 | 20 | 21 | {% include '@ui/atoms/Button/Button.twig' with { 22 | href: '#main', 23 | label: __('Aller au contenu principal', 'studiometa'), 24 | attr: { 25 | class: 'sr-only focus:not-sr-only' 26 | } 27 | } only %} 28 | 29 | {# Header #} 30 | {% block header %} 31 | {% include 'organisms/header.twig' %} 32 | {% endblock %} 33 | 34 | {# Content #} 35 |
36 | {% block content %} 37 | Sorry, no content 38 | {% endblock %} 39 |
40 | 41 | {# Footer #} 42 | {% block footer %} 43 | {% include 'organisms/footer.twig' %} 44 | {% endblock %} 45 | 46 | 47 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/molecules/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiometa/wordpress-project/8f43d408e517659cec6df011e05f72ab401ce27f/web/wp-content/themes/studiometa/templates/molecules/.gitkeep -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/molecules/video.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Video 5 | * 6 | * @params {Array} $video 7 | * @params {Array} $video_cover 8 | * @params {String} $video_legend 9 | * @params {Boolean} $video_landscape 10 | * @params {String} $classes 11 | * 12 | * Instructions: 13 | * - Video take ratio of cover image 14 | * - Change play icon svg 15 | * - Feel free to change styles 16 | */ 17 | #} 18 |
19 |
20 |
21 |
22 |
24 | {% include '@ui/atoms/Button/Button.twig' with { 25 | icon: 'play', 26 | icon_only: true, 27 | attr: { 28 | aria_label: __('Lire la vidéo', 'studiometa') 29 | } 30 | } only %} 31 | {% if video_legend %} 32 | {{ video_legend }} 33 | {% endif %} 34 |
35 | {% include '@ui/atoms/Figure/Figure.twig' with { 36 | src: video_cover.url, 37 | alt: video_cover.alt, 38 | width: video_cover.width, 39 | height: video_cover.height, 40 | img_attr: { 41 | class: ['object-contain', 'h-auto'] 42 | } 43 | } only %} 44 |
45 | 46 | 52 |
53 |
54 |
55 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/organisms/blocks/block-accordion.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Block Accordeon 5 | * Use https://ui.studiometa.dev/-/components/molecules/Accordion/ 6 | * Display a title with an accordeon list 7 | * 8 | * @param {Array} $block 9 | * @param {String} $block.title Text 10 | * @param {Array} $block.list 11 | * @param {String} $block.list.title Text 12 | * @param {Wysiwyg} $block.list.content Text 13 | * @param {String} $block_name machine name 14 | */ 15 | #} 16 |
17 |
18 |

19 | {{ block.title }} 20 |

21 | 22 | {% embed '@ui/molecules/Accordion/Accordion.twig' 23 | with { 24 | items: block.list 25 | } 26 | %} 27 | {% block title %} 28 | {{ item.title }} 29 | {% endblock %} 30 | {% block content %} 31 |
32 | {{ item.content|e('wp_kses_post')|raw }} 33 |
34 | {% endblock %} 35 | {% endembed %} 36 |
37 |
38 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/organisms/blocks/block-image-text.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Block Image + Text 5 | * Display section with image and texte on left or right 6 | * 7 | * @param {Array} $block 8 | * @param {Object} $block.image Image 9 | * @param {Wysiwyg} $block.content Text 10 | * @param {Object} $block.cta Link 11 | * @param {String} $block.text_position left|right 12 | * @param {String} $block_name machine name 13 | */ 14 | #} 15 | {% set content %} 16 | {% if block.content %} 17 |
18 | {{ block.content|e('wp_kses_post')|raw }} 19 |
20 | {% endif %} 21 | 22 | {% if block.cta %} 23 | {% include '@ui/atoms/Button/Button.twig' with { 24 | label: block.cta.title, 25 | href: block.cta.url 26 | } only %} 27 | {% endif %} 28 | {% endset %} 29 | 30 | {% set image %} 31 | {% include '@ui/atoms/Figure/Figure.twig' with { 32 | src: block.image.url, 33 | alt: block.image.alt, 34 | width: block.image.width, 35 | height: block.image.height 36 | } only %} 37 | {% endset %} 38 | 39 |
40 |
41 |
42 |
51 | {% if block.text_position == 'left' %} 52 | {{ content }} 53 | {% else %} 54 | {{ image }} 55 | {% endif %} 56 |
57 |
58 | {% if block.text_position == 'right' %} 59 | {{ content }} 60 | {% else %} 61 | {{ image }} 62 | {% endif %} 63 |
64 |
65 |
66 |
67 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/organisms/blocks/block-image.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Block Image 5 | * Use https://ui.studiometa.dev/-/components/atoms/Figure/ 6 | * Display image 7 | * 8 | * @param {Array} $block 9 | * @param {Object} $block.image Image 10 | * @param {String} $block_name machine name 11 | */ 12 | #} 13 |
14 | {# @todo use Figure #} 15 |
16 | {% include '@ui/atoms/Figure/Figure.twig' with { 17 | src: block.image.url, 18 | alt: block.image.alt, 19 | width: block.image.width, 20 | height: block.image.height 21 | } only %} 22 |
23 |
24 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/organisms/blocks/block-text.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Block Text 5 | * Display content from wysiwyg text 6 | * 7 | * @param {Array} $block 8 | * @param {Wysiwyg} $block.content wysiwyg text 9 | * @param {String} $block_name machine name 10 | */ 11 | #} 12 |
13 |
14 |
15 |
16 |
17 | {{ block.content|e('wp_kses_post')|raw }} 18 |
19 |
20 |
21 |
22 |
23 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/organisms/blocks/block-video.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Block Video 5 | * Display simple video 6 | * 7 | * @param {Array} $block 8 | * @param {String} $block.title Text 9 | * @param {Object} $block.video File 10 | * @param {Object} $block.video_cover Image 11 | * @param {Object} $block.video_legend Text 12 | * @param {String} $block_name machine name 13 | * 14 | * Instructions: 15 | * Set size of your cover image and the video will take the same ratio. 16 | */ 17 | #} 18 |
19 |
20 |
21 |
22 |
23 |

{{- block.title|e('wp_kses_post')|raw -}}

24 |
25 | 26 | {% include 'molecules/video.twig' with { 27 | video: block.video, 28 | video_cover: { 29 | url: block.video_cover.url|resize(1215, 600), 30 | width: 1215, 31 | height: 600 32 | }, 33 | video_legend: block.video_legend 34 | } only %} 35 |
36 |
37 |
38 | 39 |
40 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/organisms/blocks/default.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Default block 5 | * 6 | * @param {String} $block_name machine name of the block 7 | */ 8 | #} 9 |
10 |
11 |

12 | This is the default block template 13 |

14 |

15 | Add the file: templates/organisms/blocks/{{ block_name }}.twig to your project 16 | to customize this block 17 |

18 |
19 |
20 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/organisms/footer-menu.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Footer menu 5 | * 6 | * @param {array} $menu 7 | */ 8 | #} 9 | {% if menu %} 10 |
    11 | {% for item in menu %} 12 |
  • 13 | {{ item.title }} 14 |
  • 15 | {% endfor %} 16 |
17 | {% endif %} 18 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/organisms/footer.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Footer 5 | * 6 | */ 7 | #} 8 |
9 | 14 |
15 | 16 | {{ function('wp_footer') }} 17 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/organisms/header.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Header 5 | * 6 | */ 7 | #} 8 | 17 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/organisms/menu.twig: -------------------------------------------------------------------------------- 1 | {% if menu %} 2 |
    3 | {% for item in menu %} 4 |
  • 5 | {{ item.title }} 6 | {% include 'organisms/menu.twig' with { 7 | menu: item.children 8 | } %} 9 |
  • 10 | {% endfor %} 11 |
12 | {% endif %} 13 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/organisms/pagination.twig: -------------------------------------------------------------------------------- 1 | {% if posts.pagination.pages is not empty %} 2 | {% with posts %} 3 | 38 | {% endwith %} 39 | {% endif %} 40 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/organisms/tease-post.twig: -------------------------------------------------------------------------------- 1 | {% extends 'organisms/tease.twig' %} 2 | 3 | {% block content %} 4 |

5 | {{ post.title }} 6 |

7 | 8 |

9 | {{ post.preview.length(25) }} 10 |

11 | 12 | {% if post.thumbnail.src %} 13 | 14 | {% endif %} 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/organisms/tease.twig: -------------------------------------------------------------------------------- 1 |
2 | {% block content %} 3 |

4 | {{ post.title }} 5 |

6 |

7 | {{ post.preview }} 8 |

9 | {% if post.get_thumbnail %} 10 | 11 | {% endif %} 12 | {% endblock %} 13 |
14 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/pages/404.twig: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/base.twig' %} 2 | 3 | {% block content %} 4 | Sorry, we couldn't find what you're looking for. 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/pages/archive.twig: -------------------------------------------------------------------------------- 1 | {# This file demonstrates using most of the index.twig template and modifying 2 | just a small part. See `search.twig` for an example of another approach #} 3 | 4 | {% extends 'pages/index.twig' %} 5 | 6 | {% block content %} 7 |

8 | This is my archive 9 |

10 | 11 | {{ parent() }} 12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/pages/front-page.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Front Page 5 | */ 6 | #} 7 | {% extends 'layouts/base.twig' %} 8 | 9 | {% block content %} 10 |
11 |

12 | {{ post.title }} 13 |

14 |
15 | {{ post.content|e('wp_kses_post')|raw }} 16 |
17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/pages/index.twig: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/base.twig' %} 2 | 3 | {% block content %} 4 | {% for post in posts %} 5 | {% include ['organisms/tease-' ~ post.post_type ~ '.twig', 'organisms/tease.twig'] %} 6 | {% endfor %} 7 | 8 | {% include 'organisms/pagination.twig' with { 9 | pagination: posts.pagination({ 10 | show_all: false, 11 | mid_size: 3, 12 | end_size: 2 13 | }) 14 | } %} 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/pages/page-plugin.twig: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/base.twig' %} 2 | 3 | {% block content %} 4 |
5 | {{ content }} 6 |
7 | 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/pages/page-template-builder.twig: -------------------------------------------------------------------------------- 1 | {# 2 | /** 3 | * @file 4 | * Page Template Builder 5 | * 6 | * @param {array} $builder 7 | */ 8 | #} 9 | {% extends 'layouts/base.twig' %} 10 | 11 | {% block content %} 12 |
13 | {% for item in builder %} 14 | {% set block_name = 15 | item.acf_fc_layout|replace({ 16 | '_': '-' 17 | }) 18 | %} 19 | {% include [ 20 | 'organisms/blocks/' ~ block_name ~ '.twig', 21 | 'organisms/blocks/default.twig' 22 | ] with { 23 | block: item, 24 | block_name: block_name 25 | } only %} 26 | {% endfor %} 27 |
28 | {% endblock %} 29 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/pages/page.twig: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/base.twig' %} 2 | 3 | {% block content %} 4 | 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/pages/search.twig: -------------------------------------------------------------------------------- 1 | {# see `archive.twig` for an alternative strategy of extending templates #} 2 | {% extends 'layouts/base.twig' %} 3 | 4 | {% block content %} 5 | {# see `base.twig:27` for where this block's content will be inserted #} 6 |
7 | {% for post in posts %} 8 | {% include ['organisms/tease-' ~ post.post_type ~ '.twig', 'organisms/tease.twig'] %} 9 | {% endfor %} 10 | 11 | {% include 'organisms/pagination.twig' with { 12 | pagination: posts.pagination({ 13 | show_all: false, 14 | mid_size: 3, 15 | end_size: 2 16 | }) 17 | } %} 18 |
19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/pages/single-password.twig: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/base.twig' %} 2 | 3 | {% block content %} 4 |
7 | 8 | 15 | 16 |
17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /web/wp-content/themes/studiometa/templates/pages/single.twig: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/base.twig' %} 2 | 3 | {% block content %} 4 |
5 |
6 | 7 |
8 |

9 | {{ post.title }} 10 |

11 | {{ _e('edit') }} 12 |
13 | {{ post.content }} 14 |
15 |
16 |
17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /wp-cli.yml: -------------------------------------------------------------------------------- 1 | path: web/wp/ 2 | --------------------------------------------------------------------------------