SamsPcbLab Part 2: WP, CSS, PHP and PCBs

I will try to describe as briefly as possible the experience of developing a platform for PCB developers on WordPress (WP) without any initial knowledge of web development, focusing on some of the nuances that may be useful to those who will follow the same path. Also, I will gladly listen to advice from experts if I am in something wrong. I know a somewhat powerful community of programmers on Habré, I understand the attitude towards WP, since I saw the minified posts about it and, in principle, I myself understand the suboptimality of such a solution. But nevertheless, in three months with the payment of only one plug-in, I managed to implement functionality on it, the third-party development of which, according to my institute friend, could cost several hundred thousand rubles and even more time. So I decided to start with a pilot version of the project,from which it will be possible to build on further - for example, as a technical specification for third-party development.





The task was to create a platform for PCB developers with the following functionality:



  • calculators that simplify the performance of specific calculations;
  • knowledge base for the development of printed circuit boards;
  • collective blog;
  • private messages.


I was initially skeptical that this could be done in WP without writing custom modules. One-page sites, blogs, online stores are simple - yes, but engineering calculations? But everything worked out - it's very good for proof-of-concept, and more on that. I will present it in the form of separate cases in order to be structured.



Again, I'm a print developer, so when I was able to achieve what I wanted from it by changing the PHP code of the plugin, I was wildly happy. That is, what I will talk about is for those who want to make a site, but they do not understand the intricacies of WP, CSS and PHP, although in general they understand programming and are not afraid of code.



1. Development tools



I did not conduct a long comparative analysis of the programs; it was enough for me that the necessary task was being solved. Here's what I used:





Here I will also include one WP-plugin - Loco Translate , simply an irreplaceable tool for creating or adjusting the translation of plugins.



As for WP itself, in the English-language YouTube segment, probably everything is told (I don't remember not finding an answer to the question that arose), there are many good channels, I would mention the WPBeginner and WordPress Tutorials channels.



2. Calculators



WP has a huge number of plugins, but performing calculations is not a typical task at all, unless it is calculating the cost of goods or insurance. But there is a plugin for this task. When I found it, I realized that the idea was realizable. Calculated Fields Form - and even in the free version, it allows you to create forms for calculations, in general, it's great. The interface and formula editor will have to be figured out, but they are logical and well documented. Here's what the edit menu looks like using one of the calculators as an example.





There are several types of fields, including those that allow you to visually arrange the content of a form, but the main ones are input (selection or direct input of a value) and output (calculated values) fields.



Each field has its own identifier with a serial number like "fieldname% n", in fact it is the name of a variable that is used in calculations in calculated fields. In this case, the service calculated fields can be hidden.



Among the ready-made functions there is everything you need even for complex calculations, including trigonometric and inverse trigonometric. The calculated field syntax allows you to use if-else branching, js functions, and third-party calls ( here's an example from the documentation). Function syntax example:



( function() {
if( fieldname3 > 100 ) return fieldname1+fieldname2;
if( fieldname3 <= 100 ) return fieldname1*fieldname2;
} ) ();


An extremely useful feature is the creation of display dependencies on the values ​​of select fields. Here is the relevant section from the documentation, and here's what it looks like in an example:





To be honest, the plugin just saved me. Of course, the pages turned out to be cumbersome, because in some calculations there are several dozen calculated fields and complex formulas. I want it to fly, so my plans are to deal with the call of third-party functions that would facilitate the interface, although I still have no idea how to do this. Well, here's a step-by-step, I'll figure it out.



More from experience, what would I recommend:



  1. Excel ( , : «», «POW»), , .
  2. , , . , .
  3. (, ) ' '.
  4. – «Div», . , . «» , «».


3.



Some plugins provide basic functionality in the free version, but limit the options for customizing the appearance, although customizing the display is quite simple. There are two tools for this - CSS and the PHP code itself. I will explain it as an amateur for an amateur.



3.1. Styling with CSS



For each element of the html page, you can define the display style using CSS:



CSS- {
_1: ;
_2: ;
}


You just need to google about selectors and properties, web development is generally very well documented, even in Russian, so no problem. I will only give some comments.



To find out which style is applied to an element and what its identifier is, you need Firefox Developer Edition or equivalent. Right-clicking on an element and selecting “Inspect Element” displays a charm.







Let's look at selectors in this example. The element of interest is the username input field. The html code contains a class and an id, so you can use as a selector:



.input-text input           // ._ _ (. 1)
input.input-text            // _._ (. 2)
#fep-message-top input      // #id _ (. 1)
input#fep-message-top       // _#id (. 2)
#fep-message .input-text    // #id _


The id selector is more "strong", as there cannot be elements with the same id on the same page. So if a particular plugin form is used only on one page or the display style is suitable for all cases, then an id selector is what you need. But what if no id is set for the element, which is often the case. Then it is worth looking at the presence of id in parent blocks. For example, in this case, the container has id = "user_box". Then the element can be accessed like this:



div#user_box input      // _#id _


Nesting can be more. As an example:



div.fep-field div.field-with-icon input     //      


Since in this case access is not id, the style described for this selector will be applicable to both the username input field and the message subject input field (both in containers of the "field-with-icon" class).



Another option that may come in handy is a property value selector. For this example:



input[type="text"] //    «type»


I think the essence is roughly clear, trial and error works great here. The beauty is that Firefox DE allows you to edit page code, selectors, properties on the fly. We achieve the desired result - and transfer the resulting changes to the server. There are three methods for this:



  • in the plugin, the settings may contain a field like "Custom CSS", "Additional Styles", etc .;
  • the same in the theme's appearance settings;
  • make changes to the source file with CSS (highlighted in the picture above) - with this method I did not succeed with the general style file of the theme style.css, there is something tricky to do.


Between the values ​​of the same property in different selectors, the one with the highest priority will always be selected. The logic is that the local definition has a higher priority than the global one. In the case when it is impossible to override a property using a selector, that is, the "! Important" modifier, which raises the priority of the value:



input[type="text"] {
padding-left: 40px !important; //   
}


The last thing to say about selectors is the “@media” construct for responsive styles, which activates the selector under certain conditions: minimum or maximum display width, etc. Here's a usage example:



@media(max-width:650px) {     //   
   .comment-body .avatar {
        width: 50px !important;    //    
}
}


As for the properties themselves, there are a lot of them and you need to look at the documentation for a specific task. The easiest thing to do is change the color, positioning, and copy the finished style. It is convenient to select the color on the fly in Firefox DE. Regarding positioning, you need to understand the different values ​​of the "display" property and read, for example, this article.



3.2. Customizing the display with PHP



The two main reasons for editing the PHP plugin code are text replacement and page layout editing.



3.2.1. Replacing text



As for the first one, in an amicable way, it should be solved using the settings menu of the plugin itself, or using the Loco Translate plugin. How does plugin localization work in general? The language of the site is selected in the general settings in the WP console and this determines which translation file will be used. The translation file (extension .po) has the following structure:



#: utilities.php:1910 utilities.php:2095     //     
msgid "Lost your password?"                    //  
msgstr " ?"                        // 


In the corresponding line of the utilities.php file (1910th, for example) we find:



$str .= '<div class="impu-form-links-pass"><a href="'.$lost_pass_page.'">'.__('Lost your password?', 'ihc').'</a></div>';


Here you can see the original string and the id of the text domain of the plugin 'ihc', and the translated string will be substituted as a result. Loco Translate provides a simple and convenient interface for working with translation files.





Sometimes these lines contain characters that define the output formats -% s,% d, etc. - in translation they, of course, need to be preserved. With them, by the way, there are problems with the plural and different endings for different numbers ("3 comments", "5 comments"), you have to get out.



So, sometimes, if the developers do not indicate the entry in the translation file, then it cannot be reached by the above method. You have to act differently. All plugin files are downloaded from the / wp-content / plugins / plugin_name directory and by searching for a string or part of a string (Total Commander or an equivalent to help) search for the php file that contains it (it's good if it is unique, not " Login "). And you can either replace the string directly in the code, or add an entry into the translation file and make the desired translation.



3.2.2. Editing the layout



A situation may arise when you want to change something that does not change in the plugin or theme settings. I'll break down one example here. If this section arouses interest and questions, I will supplement it. Most of all, I was modifying the Front End PM plugin for personal correspondence . Unpopular functionality, so this is probably the only plugin that implements it, so the elaboration in the display part is low. I put back the original file that formed the top block of the page to show how it was done sequentially.





We find through the "Inspect Element" the block that we want to change and look for unique identifiers for search - these are plugin-specific class names or id, first of all. Here id = “fep-header” is set for the common container. Searching for the occurrence of a line leads to a file with the self-explanatory name header.php. Open up with VS Code and observe the following code:



<div id="fep-header" class="fep-table">
        <div>
            <div>
                <?php echo get_avatar( $user_ID, 64, '', fep_user_name( $user_ID ) ); ?>
            </div>
            <div>
                <div>
                    <strong><?php esc_html_e( 'Welcome', 'front-end-pm' );?>: <?php echo fep_user_name( $user_ID ); ?></strong>
                </div>
                <div>
                    <?php echo strip_tags( sprintf( __('You have %1$s and %2$s unread', 'front-end-pm'), '<span class="fep_unread_message_count_text">' . sprintf( _n( '%s message', '%s messages', $unread_count, 'front-end-pm' ), number_format_i18n( $unread_count ) ) . '</span>', '<span class="fep_unread_announcement_count_text">' . sprintf( _n( '%s announcement', '%s announcements', $unread_ann_count, 'front-end-pm' ), number_format_i18n( $unread_ann_count ) ) . '</span>' ), '<span>' ); ?> 
                </div>
                <div class="<?php echo $box_class; ?>">
                    <?php echo strip_tags( sprintf( __( 'Message box size: %1$s of %2$s', 'front-end-pm' ), '<span class="fep_total_message_count">' . number_format_i18n( $total_count ) . '</span>', $max_text ), '<span>' ); ?>
                </div>
            </div>
            <?php do_action( 'fep_header_note', $user_ID ); ?>
        </div>
    </div>


For those unfamiliar with PHP (like me), it looks like HTML but with <? Php ... code ...?> Inserts. These inserts are used to form an HTML page depending on various parameters, for example, user data. That is, PHP is such a static page constructor, and JavaScript is used to handle complex events.



I copied the style of the top panel from the more detailed plugin, removed unnecessary information about the size of the mailbox, changed the way information about new messages is displayed. This is what happened in the code and in the display.



<div class="fep-header">
        <div class="fep-header-left-side">
            <div class="fep-user-page-avatar">
                <?php echo get_avatar( $user_ID, 96, '', fep_user_name( $user_ID ) ); ?>
            </div>
        </div>
        <div class="fep-header-right-side">
            <div class="fep-header-username">
                <?php echo fep_user_name( $user_ID );?>
            </div>
            <div class="fep-header-top-info">
                <?php
                    if( $unread_count == 0 && $unread_ann_count == 0 )
                    {
                        echo sprintf( __('    .', 'front-end-pm'));
                    }else{
                        if( $unread_count != 0 )
                            echo sprintf( __(' : %d<br>', 'front-end-pm'), $unread_count);
                        if( $unread_ann_count != 0 )
                            echo sprintf( __(' : %d', 'front-end-pm'), $unread_ann_count);
                    }
                ?>
            </div>
        </div>
        <?php do_action( 'fep_header_note', $user_ID ); ?>
        <div class="fep-top-background"></div>
    </div>




Naturally, the process is iterative and not very convenient, but I resigned myself. Perhaps there are more convenient ways. Save the file (VS Code), replace the file on the server (FileZilla), refresh the page (Firefox DE). This is not the most difficult case, but it shows the essence of the process. It is the same in more complex tasks - with changes in functions, classes and data arrays, and in simpler tasks - when you just need to swap blocks or delete unnecessary ones.



But this approach makes the update process much more difficult. After the update, probably (I didn’t do it as long as it works according to the principle "it works and it is good"), you will have to re-make the edits. This is probably the main disadvantage.



4. Performance



WP is not about speed. Attempts to improve the download speed, to be honest, did not lead to a significant increase, but did lead to a malfunction. I used the Asset CleanUp plugin to remove unnecessary CSS / JS loading, but did not notice a noticeable increase in loading speed (I looked at GTmetrix ), but I noticed that some plugins climb on all pages regardless of whether they are used there or not. In the end, I turned it off. Then I tried W3 Total Cachefor caching pages on the server - when the page is not generated using PHP, but a ready copy is loaded (which is periodically updated). But with it my site crashed, and then I also saw that the recommended setting is not to cache pages for logged in users, it became clear that caching pages in my case is quite difficult to set up. I left only partial caching of pieces of code, I will figure it out more (sometimes now you have to reset the cache for changes to plugin settings to take effect).



In general, I think that in some cases it works great, but it didn't help me out of the box right away. As far as I understand, the paid WP Rocket has a caching option for each user, maybe I'll try it later.



5. Security



At one time at the institute he studied the specialty "Information Security". Although after graduation he began to engage in electronics, professional deformation remained. That the Internet is leaky in terms of security. I can imagine how many vulnerabilities there are in WP with its piled-up structure. Not everyone can be patched, but I did the simplest things in the footsteps of this instruction and installed Wordfence - let's see if performance does not suffer much, you can leave it.



6. Plugins



6.1. User and access management



To solve the problem, I chose the Indeed Ultimate Membership Pro plugin ($ 41). There are separate video tutorials on it - here. I had to tinker, a lot of settings, but I will not write about everything in detail, if I have questions, I will answer in the comments or in private messages. I will only tell you about the methods of access control.

Basically, there are several roles in the system (which was originally tailored for blogs), and many plugins work with them, controlling the capabilities depending on the role. The default role is set in "Settings> General".





The subscription management plugin adds another layer - the subscription level, in accordance with which you can control access to content and its display for each page, including the display of menu items. Also, users are divided into registered and unregistered - this is another way to separate the display of content.



The plugin is not without flaws, but it does its job. There are many settings, but there are training videos, you can figure it out, technical support, if anything, will support and tell you.



6.2. Knowledge base



At first I placed the book on the platform using the pdf viewer plugin, but there is no way to create links to the material, and pdf is not the most flexible option for viewing. Refused and decided to go to the knowledge base. I'll just call the plugin Echo Knowledge Base , it's really good. But as for viewing pdf - I can't help but mention the Flowpaper plugin , it is very beautiful, maybe it will be useful to someone.



6.3. Voting



I liked the Yop Poll plugin - again, there is everything you need, all the settings, even the appearance is quite good on the free version.



7. What didn't work



A collective blog needs the ability for users to create posts. The choice is not great - the User Submitter Posts plugin (there is also such a paid one). I even bought its paid version, but it killed my authorization form, a conflict with the subscription management plugin - I returned the money, the developer did not solve the issue, blamed everything on other plugins. But that's not the point. The publication creation form does not provide an opportunity to upload and insert images into the publication.





Began to understand the rights, it was useful, installed a useful plugin User Role Editor . So it turned out to load the image only when the user was given the rights to edit all pages. Tin full, of course, disabled, while you can only put a URL link to images. The problem here is that the post doesn't exist yet and WP looks at adding the image as editing the page that contains the post creation form. Maybe someone can tell you how to solve this plug?



8. Conclusion



WP made it possible to create at minimal cost a pilot project of a platform with not the simplest functionality. He solved his problem by creating a starting point for further development. If you have additional questions about the content of the post, I will be happy to share my experience. I will also be grateful for the comments and recommendations of specialists (to improve performance - will a CDN like CloudFlare, or a paid WP Rocket, specialized hosting like WP Engine, or Wordfence actually needed).



Good luck to all!



All Articles