<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Giulio Ganci</title>
    <description>The latest articles on DEV Community by Giulio Ganci (@toriphes).</description>
    <link>https://dev.to/toriphes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F413845%2F2a042fbd-be00-4568-b259-4b590a97709c.jpeg</url>
      <title>DEV Community: Giulio Ganci</title>
      <link>https://dev.to/toriphes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/toriphes"/>
    <language>en</language>
    <item>
      <title>Dealing with images when developing on localhost with wordpress</title>
      <dc:creator>Giulio Ganci</dc:creator>
      <pubDate>Thu, 02 Jun 2022 22:16:43 +0000</pubDate>
      <link>https://dev.to/toriphes/dealing-with-images-when-developing-on-localhost-with-wordpress-11gd</link>
      <guid>https://dev.to/toriphes/dealing-with-images-when-developing-on-localhost-with-wordpress-11gd</guid>
      <description>&lt;p&gt;Many developers tend to work on new features directly on the production server, asserting that configuring a wordpress development environment locally for a site already online has the following disadvantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Too much time to configure&lt;/li&gt;
&lt;li&gt;Too much disk space occupied by images&lt;/li&gt;
&lt;li&gt;It's just a website...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ignoring the last point, in my mind I always think "We are developers, We are smart!" regardless of what we are developing: webapp, website in wordpress or a cooking recipe.&lt;/p&gt;

&lt;p&gt;A developer uses methodologies and tools to maximize the result with minimal effort (sometimes 😂).&lt;/p&gt;

&lt;p&gt;Now I'll show you my personal recipe of how I prepare my local development environment for a wordpress site.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before start
&lt;/h2&gt;

&lt;p&gt;I assume you have a minimum of experience in developing websites on wordpress.&lt;/p&gt;

&lt;p&gt;In this post I will not cover the configuration of the AMP stack, however there are several solutions on the market such as &lt;a href="https://www.mamp.info/"&gt;MAMP&lt;/a&gt;, &lt;a href="https://www.vagrantup.com/"&gt;Vagrant&lt;/a&gt; or &lt;a href="https://laravel.com/docs/valet"&gt;Valet&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloning and configuring
&lt;/h2&gt;

&lt;p&gt;When I set up my environment I generally start with these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download wordpress in your local environment making sure to have the same wordpress version as the online website.&lt;/li&gt;
&lt;li&gt;Download themes and plugins from the remote site&lt;/li&gt;
&lt;li&gt;Dump the sql database from the remote server and import it into your local mysql server.&lt;/li&gt;
&lt;li&gt;Review your local &lt;code&gt;wp-config.php&lt;/code&gt; file to make your wordpress site start correctly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It may seem like a lot of work, but you only do it once.&lt;/p&gt;

&lt;p&gt;After importing the the database I usually apply a search and replace to change the hostname. For example, if the published website address is &lt;code&gt;www.exmaple.com&lt;/code&gt; I will replace it with &lt;code&gt;www.example.com.local&lt;/code&gt; using the &lt;a href="https://wp-cli.org/"&gt;wp-cli&lt;/a&gt; tool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wp search-replace &lt;span class="s1"&gt;'www.example.com'&lt;/span&gt; &lt;span class="s1"&gt;'www.example.com.local'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may also use &lt;code&gt;sed&lt;/code&gt; command from the terminal to apply the replacement directly in the dump file before importing it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt;.bak &lt;span class="s1"&gt;'s/www.example.com/www.example.com.local/g'&lt;/span&gt; your-wordpress-db-dump-file.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both approach are fine for me.&lt;/p&gt;

&lt;p&gt;Be careful, wordpress uses the &lt;code&gt;serialize&lt;/code&gt; and &lt;code&gt;unserialize&lt;/code&gt; functions to save and restore several type of data in the database so this operation could break some configuration in your theme or plugins that use these functions to save information related to the site hostname.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tweaking the .htaccess
&lt;/h2&gt;

&lt;p&gt;We don't need to download all the images from the remote site because these are already available online right? So this is where our trick begins.&lt;/p&gt;

&lt;p&gt;Assuming our website is available at the address &lt;code&gt;www.example.com&lt;/code&gt; add these lines to your &lt;code&gt;.htaccess&lt;/code&gt; file after the &lt;code&gt;RewirteBase&lt;/code&gt; directive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="nc"&gt;RewriteCond&lt;/span&gt; %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
&lt;span class="nc"&gt;RewriteRule&lt;/span&gt; (.*?)(\.gif|\.jpe?g|\.png|\.bmp) https://www.example.com/$1$2 [NC,L]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these line we're telling the web server "If a file is not present in the documents root and its extensions is one of the image types listed in the regex, then rewrite the local url to point to the online website where the image we know exists". Brilliant isn't it? &lt;/p&gt;

&lt;p&gt;Now your local wordpress development environment is now ready.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;This is not the best solution to deal with this kind of problems but I believe it is useful in several cases, the drawback is that it is necessary to have an active internet connection.&lt;/p&gt;

&lt;p&gt;I suggest to use a similar approach in website development since wordpress handle the "not found" images through an internal php route which makes the loading of each web site page kinda slow.&lt;/p&gt;

&lt;p&gt;Following the example shown previously in this post you may create a variant of the &lt;code&gt;.htaccess&lt;/code&gt; to show a placeholder image for all not found images in your local environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="nc"&gt;RewriteCond&lt;/span&gt; %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
&lt;span class="nc"&gt;RewriteRule&lt;/span&gt; \.(gif|jpe?g|png|bmp) /placeholder.jpg [NC,L]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just put a &lt;code&gt;placeholder.jpg&lt;/code&gt; file in your web root and you're done.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>htaccess</category>
      <category>images</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Using stacked modals with Ionic Vue</title>
      <dc:creator>Giulio Ganci</dc:creator>
      <pubDate>Thu, 04 Feb 2021 22:05:09 +0000</pubDate>
      <link>https://dev.to/toriphes/using-stacked-modals-with-ionic-vue-m8i</link>
      <guid>https://dev.to/toriphes/using-stacked-modals-with-ionic-vue-m8i</guid>
      <description>&lt;p&gt;Since ionic 5 has been released it is possible to use a new component of the &lt;a href="https://developer.apple.com/design/human-interface-guidelines/ios/app-architecture/modality/"&gt;iOS UI Kit&lt;/a&gt; that allows you to open content in a temporary mode that’s separate from the user's previous current context.&lt;/p&gt;

&lt;p&gt;These contents are presented in a stack managed by the &lt;a href="https://ionicframework.com/docs/api/modal"&gt;ionic modal controller&lt;/a&gt; and while they work very well on @ionic/angular and @ionic/react they are not yet fully supported in @ionic/vue but there is a way to have this feature working using a workaround, so be careful if using it in production.&lt;/p&gt;

&lt;p&gt;In order to use stacked modals you need to have access to the current &lt;code&gt;IonRouterOutlet&lt;/code&gt; reference but currently there is no official method to have a reference to it, so we use the vue3 &lt;a href="https://v3.vuejs.org/guide/component-provide-inject.html#provide-inject"&gt;provide&lt;/a&gt; method to serve a reference from the app component and the &lt;a href="https://v3.vuejs.org/guide/component-provide-inject.html#provide-inject"&gt;inject&lt;/a&gt; method to access it in each child component.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;/src/App.vue&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;IonApp&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ion-router-outlet&lt;/span&gt;
      &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"routerOuteletRef"&lt;/span&gt;
      &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"main-content"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&amp;lt;/ion-router-outlet&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/IonApp&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;IonApp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IonRouterOutlet&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@ionic/vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;provide&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;defineComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;IonApp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;IonRouterOutlet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// create an empty ref&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routerOuteletRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// provide the value in the component hierarchy&lt;/span&gt;
    &lt;span class="nx"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;routerOutlet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;routerOuteletRef&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;routerOuteletRef&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we use a generic "Home" component which contains a button that opens a new modal view of the same "Home" component&lt;/p&gt;

&lt;p&gt;Note that stacked modals are activated by passing the presentingElement option to the modal controller.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;/src/view/Home.vue&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;modalController&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@ionic/vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Home.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;defineComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;outlet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;routerOutlet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;openModal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// use the last presenting element&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;modalController&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getTop&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;outlet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$el&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;modalController&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;swipeToClose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;presentingElement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;top&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;present&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;openModal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://codesandbox.io/s/ionic-vue-stacked-modals-vnnuy"&gt;Here a fully working&lt;/a&gt; example in code sandbox.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/vnnuy"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>ionic</category>
      <category>vue</category>
      <category>modal</category>
      <category>ios</category>
    </item>
  </channel>
</rss>
