<?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: Tomislav Buljević</title>
    <description>The latest articles on DEV Community by Tomislav Buljević (@tomebuljevic).</description>
    <link>https://dev.to/tomebuljevic</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%2F162955%2F105cc5dc-9e35-4ba2-a9ec-d97dd3ca6c35.jpg</url>
      <title>DEV Community: Tomislav Buljević</title>
      <link>https://dev.to/tomebuljevic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tomebuljevic"/>
    <language>en</language>
    <item>
      <title>Web development déjà-vu: Exploring the contact cycle</title>
      <dc:creator>Tomislav Buljević</dc:creator>
      <pubDate>Fri, 21 Feb 2025 13:41:50 +0000</pubDate>
      <link>https://dev.to/tomebuljevic/web-development-deja-vu-exploring-the-contact-cycle-3fim</link>
      <guid>https://dev.to/tomebuljevic/web-development-deja-vu-exploring-the-contact-cycle-3fim</guid>
      <description>&lt;p&gt;Web development often feels like déjà vu. The patterns — recognizing a need, brainstorming solutions, tackling challenges, and reflecting on results — repeat themselves across projects. Interestingly, this process mirrors the “contact cycle” from Gestalt psychotherapy, which explains how humans recognize and satisfy needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gestalt psychotherapy and the contact cycle
&lt;/h2&gt;

&lt;p&gt;Gestalt therapy is a type of humanistic, person-centred therapy that focuses on the immediate “here and now” and how that can be explored to help you. It looks at how your past influences what you’re feeling in this moment, rather than how you felt back then. According to Gestalt therapy, “the contact cycle” is a cyclical model that describes our response to any particular need —from the initial recognition of the need to satisfying it and integrating what the experience taught us.&lt;/p&gt;

&lt;p&gt;To be aware of the contact cycle, we must understand its natural stages and the importance of those stages. As in Gestalt therapy, awareness is key to identifying the needs and challenges of a team. Without it, “contact breaks” — deviations from the process — can remain unresolved and carry over to future projects. That’s why it’s important to understand where and why these breaks occur and to develop strategies to guide the project to completion. Fortunately, we have several readily available support mechanisms which can help in the process itself.&lt;/p&gt;

&lt;p&gt;In this article, I intend to show how applying the contact cycle can help you navigate the ups and downs of web development. You’ll uncover hidden pitfalls, discover actionable strategies to keep your projects on track, and ultimately create a smoother, more rewarding workflow for your team.&lt;/p&gt;

&lt;p&gt;We’ll break down each stage of the contact cycle —from recognizing the need to reflecting on results — and show how to overcome challenges at every step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Precontact (sensitisation): Recognizing the need
&lt;/h2&gt;

&lt;p&gt;In this stage, we identify a need, and our interest is piqued. This is the stage right before a project begins, where the team decides on the solution, and the way a project can be realized. This stage is brimming with ideas (Gestalt’s “fertile void”) and various approaches to solving the problem. During this stage, fostering autonomy is crucial. By allowing team members to voice their ideas, we can empower them to take ownership of the project’s direction. This sense of ownership can fuel engagement.&lt;/p&gt;

&lt;p&gt;To succeed in this stage, it’s important to stay focused on the project’s true need and to continually ask ourselves: “Why are we doing this?”&lt;/p&gt;

&lt;h3&gt;
  
  
  Possible contact breaks
&lt;/h3&gt;

&lt;p&gt;Unresolved issues from past projects can make the current project feel like a low-priority one. Additionally, too many ideas can distract from understanding the true user need.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Your team brainstorms a user notification system, but the discussion shifts to exploring all possible channels of delivery. Instead of focusing on one viable option for the MVP, the team becomes bogged down by exploring all the possible solutions and libraries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Support mechanisms
&lt;/h3&gt;

&lt;p&gt;When we get a request from the management to plan for a new feature, it is important to conduct user research and surveys to identify real user needs. After all, if a user doesn’t need this particular project, what is the point of doing it in the first place?&lt;/p&gt;

&lt;p&gt;Also, organizing brainstorming sessions with all team members is extremely important to prevent unresolved past projects from interfering with the current one.&lt;/p&gt;

&lt;p&gt;Documenting user stories in the backlog is essential for creating a viable plan to enter the project, as well as determining the MVP (Minimal Viable Product), so that the team can focus on the essentials.&lt;/p&gt;

&lt;p&gt;The previously mentioned discussion about user notifications might be steered back to focusing only on the MVP. This way, everyone in the team is on the same page in defining the MVP, and not veering off track significantly.&lt;/p&gt;

&lt;p&gt;Once the groundwork has been laid in the Precontact phase, we can naturally transition into the Mobilization stage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mobilization: Starting work
&lt;/h2&gt;

&lt;p&gt;Mobilization turns plans into action, which comes with its own unique set of challenges. In this stage, in order to make sure the team is aligned and efficient, we should ensure that team members are entrusted with ownership of their part of the project. Trusting their expertise reduces the need for micromanagement and creates a sense of accountability. This is the point where team members should begin work, make decisions, and keep moving forward.&lt;/p&gt;

&lt;h3&gt;
  
  
  Possible contact breaks
&lt;/h3&gt;

&lt;p&gt;Contact breaks stem from doubts about personal abilities or from questioning the project’s purpose and relevance.&lt;/p&gt;

&lt;p&gt;In Gestalt terms, when we assimilate an idea, belief, attitude or some other negative aspect from our environment without question or thought, we are “introjecting”. These negative beliefs, called “introjects”, don’t have to be confirmed, but they still represent our own personal truths, shaped by previous projects or experiences. Introjects can create doubts or resistance.&lt;/p&gt;

&lt;p&gt;Also, if there are any unresolved questions from the Precontact stage, this can also influence team members, leading to doubts and misalignment in their understanding of the common goal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;You have started working on your notification system. But your junior developer feels unmotivated and doubts their abilities, leading to missed deadlines despite assigned tasks suited to their level.&lt;/p&gt;

&lt;h3&gt;
  
  
  Support mechanisms
&lt;/h3&gt;

&lt;p&gt;To overcome challenges in the mobilization stage, we need to ensure that everyone clearly understands their task. Kanban boards are immensely helpful with that. Breaking down user stories into small tasks helps team members keep focus and push the project forward. Team alignment meetings and frequent one-on-one discussions can help us overcome contact breaks during this crucial stage. The goal of these strategy meetings is to challenge introjects through evidence-based discussions, enabling team members to adjust their perspectives and align with project goals.&lt;/p&gt;

&lt;p&gt;Keeping this in mind, consider having a one-on-one with the junior developer to discuss why they don’t feel up to par. Understanding their introjects —and sometimes sharing your own — can be a powerful way to challenge and even eliminate these negative beliefs.&lt;/p&gt;

&lt;p&gt;As Mobilization progresses, one of the impediments to reaching the next stage can be Projection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Projection: Unconscious bias
&lt;/h2&gt;

&lt;p&gt;Projection occurs when team members blame external factors for internal struggles, avoiding accountability for their own shortcomings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;A member of your team starts explaining how they couldn’t do their work in time due to a tool slowing them down, the architecture not being well-defined, or tasks being unclear. Yet, in the Precontact stage, they had no problem understanding what needed to be done.&lt;/p&gt;

&lt;h3&gt;
  
  
  Support mechanisms
&lt;/h3&gt;

&lt;p&gt;The key support mechanism is accountability. Hold regular check-ins, where team members evaluate their own contributions before critiquing others. These issues can also be raised during retrospectives.&lt;/p&gt;

&lt;p&gt;Having clear communication channels with defined guidelines helps prevent misinterpretation.&lt;/p&gt;

&lt;p&gt;And when all else fails, having a neutral facilitator, such as a Scrum Master, to mediate discussions and identify the root causes of the tension can keep the team focused on collaboration, avoiding internal strife.&lt;/p&gt;

&lt;p&gt;Getting back to our example, the team member in question could discover during a retrospective that the real issue lies in their workflow. This could trigger a discussion about optimizing individual practices, which could, in turn, help the team member address their own projection.&lt;/p&gt;

&lt;p&gt;Once Projections have been successfully resolved, the project reaches a state of maximum efficiency: the Full Contact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full contact: Maximum efficiency
&lt;/h2&gt;

&lt;p&gt;Full Contact is the stage when everything finally falls into place. At this point, everyone understands their needs and tasks, and works together well, with energy to spare. Everyone feels like they are contributing, taking ownership of the project, and performing at their optimal output. Everybody feels “seen”, which basically gives each team member their own little personal reward.&lt;/p&gt;

&lt;h3&gt;
  
  
  Possible challenges
&lt;/h3&gt;

&lt;p&gt;The challenge here is maintaining team energy and output.&lt;/p&gt;

&lt;p&gt;To sustain that full contact experience, regular sprint reviews can help refresh team motivation. “Showing off” team successes can help them feel seen and keep their energy levels high. Positive feedback and small celebrations help maintain team motivation during this stage.&lt;/p&gt;

&lt;p&gt;However, having high energy and high output levels could also lead to burnout if we are not careful in planning breaks from work. To prevent this, the team should schedule regular team check-ins to gauge stress levels. Time-off policies or flexible work arrangements can also contribute to maintaining long-term energy without overwhelming team members.&lt;/p&gt;

&lt;p&gt;As the project nears completion and final touches are added, the stage of Differentiation starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Differentiation: Letting go
&lt;/h2&gt;

&lt;p&gt;Differentiation is the stage when team members emotionally detach from the project —a necessary step for closure. However, this stage can lead to conflicts, as emotional investment in the work often runs high. Healthy detachment is crucial, but may cause insecurity, over-identification, or fear of success.&lt;/p&gt;

&lt;h3&gt;
  
  
  Possible contact breaks
&lt;/h3&gt;

&lt;p&gt;Contact breaks stem from over-identification, where feedback is taken personally, leading to defensiveness. There may also be a fear of finishing, driven by perfectionism or fear of judgment. In Gestalt theory, this is referred to as Confluence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Your team can see the light at the end of the tunnel. The deadline is approaching, and a couple of bugs unexpectedly surface — something nobody accounted for, something natural. However, the developer working on that part of the feature starts making excuses when the bugs are mentioned in the daily meeting, vehemently explaining why the bugs occurred. They go into an almost panic mode — something out of character for the person in question.&lt;/p&gt;

&lt;h3&gt;
  
  
  Support mechanisms
&lt;/h3&gt;

&lt;p&gt;Autonomy is key in this stage. We need to define a strict boundary between the team members and the project. Autonomy can be fostered through demo presentations to stakeholders, allowing team members’ solutions to be validated. Individual feedback can also help each member of the team reinforce their sense of autonomy.&lt;/p&gt;

&lt;p&gt;To address the example before, individual feedback for the developer should focus on their past successes, personal goals and the importance of separating themselves from the project results. Emphasize that finding bugs before launch is a positive outcome and foster a safe-to-fail environment.&lt;/p&gt;

&lt;p&gt;If the team handles the Differentiation stage well, they can finish strong, feeling proud of their accomplishment and ready to tackle the next project. The contact cycle is then closed with Integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration: Learning from insights
&lt;/h2&gt;

&lt;p&gt;Integration is the stage for reflection, learning, and preparing for the next step by evaluating insights from the completed project. It is healthy to identify what has been useful and discard anything that does not contribute to our future growth. We can then separate ourselves from the project and return to the “fertile void” until a new need arises. This new need starts the cycle all over again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Possible contact breaks
&lt;/h3&gt;

&lt;p&gt;As developers, we often find that we don’t have time for proper evaluation and reflection because we’re jumping to the next thing in our roadmap. However, this stage is vital for both personal and team growth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Support mechanisms
&lt;/h3&gt;

&lt;p&gt;A recommendation here is to introduce post-mortem meetings. Sounds morbid, I know, but these meetings actually use as a glance back to the finished project, so we can define lessons learned. The team’s successes and challenges can be documented in the team knowledge base to serve as a powerful resource for the projects to come.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Let’s finally wrap up our imaginary project. A post-mortem could reveal that a new architecture decision might benefit future projects as well, or that too much effort was spent on a minor issue, which could impede future work. These kinds of insights may steer your future decisions into a healthier environment for everyone involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  In conclusion
&lt;/h2&gt;

&lt;p&gt;Understanding the contact cycle helps teams identify and address challenges at each stage. Striving for Full Contact is essential, but even when stuck, teams can break free by embracing the cycle, adapting, and growing — especially since the next cycle is always just around the corner.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>softwaredevelopment</category>
      <category>watercooler</category>
      <category>writing</category>
    </item>
    <item>
      <title>I debugged my 2024 and this is what I learned</title>
      <dc:creator>Tomislav Buljević</dc:creator>
      <pubDate>Tue, 07 Jan 2025 13:41:01 +0000</pubDate>
      <link>https://dev.to/tomebuljevic/i-debugged-my-2024-and-this-is-what-i-learned-3fjd</link>
      <guid>https://dev.to/tomebuljevic/i-debugged-my-2024-and-this-is-what-i-learned-3fjd</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/newyear"&gt;2025 New Year Writing challenge&lt;/a&gt;: Retro’ing and Debugging 2024.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Dear reader, the title is, admittedly, clickbait - but can you blame me? Sometimes the easiest way to get your attention is to go for the obvious hook. Now I get why reporters do it.&lt;/p&gt;

&lt;p&gt;But before I properly debug 2024, I think a quick introduction is in order. After all, context matters - in code, and when reflecting on the last 365 days of life as we know it.&lt;/p&gt;

&lt;p&gt;So, who am I? I'm a developer. Big whoop, so are you probably, especially since you're reading it here. But I am also a husband, a father, a board-game enthusiast, a passable singer, a pop culture junkie, a gourmand of sorts, and, occasionally, a pretty annoying person to boot.&lt;/p&gt;

&lt;p&gt;We developers are as diverse as the systems we build, and while people have ideas on what a developer &lt;strong&gt;should&lt;/strong&gt; be, they rarely understand who we &lt;strong&gt;are&lt;/strong&gt;. But don't worry - this isn't a philosophical deep-dive. I'll stick (mostly) to my professional achievements, as I debug my last year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deepening my soft skills
&lt;/h2&gt;

&lt;p&gt;With over 15 years of experience, as a senior developer, I am confident there isn't a serious problem I can't handle - given enough time and preparation. Sort of like Batman. And let's be honest, we're all Batman. You can confidently whisper "I am the night" to anyone you meet.&lt;/p&gt;

&lt;p&gt;But sometimes we need to be more Bruce Wayne - focused on relationships and human connections.&lt;/p&gt;

&lt;p&gt;All joking aside, this year forced me to debug my approach to communication and leadership.&lt;/p&gt;

&lt;p&gt;Mentoring a junior developer this year has been equal parts rewarding and challenging. As they learned to tackle coding problems, I learned to adapt my approach to fit how they learn - because, surprise, nobody learns the same way. This was my first &lt;strong&gt;real&lt;/strong&gt; mentoring experience. Building a person from the ground floor (and I do mean from the ground floor) is no small feat.&lt;/p&gt;

&lt;p&gt;But it's worth it. I am proud to say my mentee exceeded my expectations, and is on their way to become an excellent developer in their own right.&lt;/p&gt;

&lt;p&gt;The hardest part for me, though, was learning to detach myself from the urge to &lt;em&gt;just do it for them&lt;/em&gt;. Developers are natural problem-solvers, so resisting that instinct and gently guiding them - talking through solutions, encouraging them to challenge others as well as me - was a lesson in patience and growth. Mentoring isn't just about code - it's about preparing someone to deploy confidently into the real world.&lt;/p&gt;

&lt;p&gt;This year, I finally stopped being apprehensive about conflict. As a developer, you know when a firm "No" is necessary, right? But that, dear reader, is only part of the equation.&lt;/p&gt;

&lt;p&gt;Sometimes we're all too caught up in deadlines, code, and responsibilities, that we forget the importance of standing up for ourselves when it matters. And no, I don't mean standing up to the business - a well-organized team should always present a united front.&lt;/p&gt;

&lt;p&gt;I'm talking about conflict within the team itself. I learned that, when approached with honesty and sincerity, conflict can actually work, if all parties involved are prepared to listen.&lt;/p&gt;

&lt;p&gt;I encountered two major conflicts this year. One was a resounding  success, completely upgrading my relationship with the other party. The other one remains uncertain. That comes back to the importance of listening - which is essential for true resolution.&lt;/p&gt;

&lt;p&gt;So, as you can see, not all of my journey into soft skills was a smooth ride. But that's exactly the point. We learn far more from our setbacks than our successes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Focusing on writing more
&lt;/h2&gt;

&lt;p&gt;Writing has always been a (not so) hidden passion of mine. I always had this feeling that there's a novel in me, just waiting to emerge - once I find the perfect topic, title, character names, and motivation to write it. While that novel is still on hold, I've discovered that blog posts provide a satisfying way to express myself through words.&lt;/p&gt;

&lt;p&gt;Throughout my career, I always found some form of writing in every company I worked for, but finding topics for blog posts has never been a small task. I probably overthought it, but I often doubted if what I was writing about had real merit.&lt;/p&gt;

&lt;p&gt;The tech landscape is ever changing, so writing tutorials which could easily become obsolete felt like a risky proposition.&lt;/p&gt;

&lt;p&gt;Last year, I managed to shake off that dread. How? Simple. I stopped writing tutorials. Yes, dear reader, I shifted my focus to the "human" side of development - the challenges we face, how it relates to our experience, and the common pitfalls we all encounter. Finding topics on this side of development has proven much easier than I imagined. And now, I can finally enjoy my writing without the pressure of keeping up with the technical tide, focusing instead on the humanity that lies behind our occupation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Polishing my tech-leading skills
&lt;/h2&gt;

&lt;p&gt;I am no stranger to taking the lead on projects. Making decisions about new features, following an established flow while adding my own twist - this is something I find both comfortable and enjoyable. Innovation is my primary motivator in this field, and I get a certain joy from anticipating pitfalls &lt;strong&gt;before&lt;/strong&gt; they arise.&lt;/p&gt;

&lt;p&gt;These moments, however, are fleeting since I don't technically hold a formal leadership position in my team. But when you get a small project to call your own, that in itself is incredibly rewarding.&lt;/p&gt;

&lt;p&gt;This year, however, something exceptional happened. It felt as if all of my previous experiences converged into the perfect storm for delivering a project &lt;strong&gt;on time&lt;/strong&gt;. Yes, dear reader, I can almost retire (not just yet) knowing that I led a project that didn't burn extra hours, was properly planned, and was executed exactly how I envisioned. Oh, the personal satisfaction it brought me - truly, you can't imagine!&lt;/p&gt;

&lt;h2&gt;
  
  
  What a year it has been
&lt;/h2&gt;

&lt;p&gt;In retrospect, 2024 has been a year of growth, challenges, and unexpected triumphs. There were inevitable ups and downs, but the lessons I've learned this year have been more profound than the years before. As I reflect on them now, I feel a deep sense of joy and fulfillment, both personally and professionally.&lt;/p&gt;

&lt;p&gt;I am truly thankful for 2024 - the year I turned 40, the year my journey in life and in my career reached new heights. It's been a year of milestones, and I'm optimistic that 2025 holds even more promise.&lt;/p&gt;

&lt;p&gt;Here's to 2025! May it be as fulfilling, if not more so, than 2024!&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>newyearchallenge</category>
      <category>career</category>
    </item>
    <item>
      <title>Cobra effect and what we can do to mitigate it</title>
      <dc:creator>Tomislav Buljević</dc:creator>
      <pubDate>Tue, 07 Jan 2025 08:43:03 +0000</pubDate>
      <link>https://dev.to/tomebuljevic/cobra-effect-and-what-we-can-do-to-mitigate-it-1i16</link>
      <guid>https://dev.to/tomebuljevic/cobra-effect-and-what-we-can-do-to-mitigate-it-1i16</guid>
      <description>&lt;p&gt;As web developers working on a product, we continuously strive to improve it, adding new features to build trust and to better connect with our users. We try to help them use our product better, coming up with solutions which can guide them and help them reach a positive result. At the end of the day, we want our users to be happy with the experience they have using our product. But, sometimes the solutions we implement can have undesired consequences. This can be due to bad actors who are trying to exploit features we implement or simply an undesirable side-effect of a feature. This is called the Cobra effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Cobra effect, though?
&lt;/h2&gt;

&lt;p&gt;Well, it all dates back to British rule of India. The British government in Delhi was concerned about the number of venomous cobras in the city. Therefore, they issued a decree in which they offered a bounty for every dead cobra brought to them. And to be honest, it seems like a win-win – they incentivize the population with money, and reduce the number of cobras, which in turn reduces the threat to human population, right?&lt;/p&gt;

&lt;p&gt;The bounty worked for a while. But, as always, people find ways to “hack” the system. A large number of cobra breeders emerged as a result. They would breed cobras and collect the bounty. Now, as soon as the government realized what had been going on, they canceled the program altogether. By that time, though, the damage had been done. The breeders released the cobras into the wild, and suddenly there was a surge in cobra population instead of the actual decrease.&lt;/p&gt;

&lt;p&gt;As you can see, situations happen where trying to fix a problem actually makes it worse. In the case of the British government, the “solution” for a problem stemmed from misunderstanding the folk of India. Their traditions are radically different from Britain’s Western sensibility, and they didn’t have enough foresight to predict the inevitable outcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cobra effect in web development
&lt;/h2&gt;

&lt;p&gt;Sometimes a feature looks good on paper. For example: You have a product, and you decide to incentivize your audience in some way. Say, you want people to sign up for a newsletter, and by doing so, they get a redeemable code for some activity on your site. One code per mail, right? But if you’re not careful, you could find yourself in a situation where a user, to get more redeemable codes than they are allowed to, makes fake email addresses, signs up for your newsletter, and then has enough redeemable codes to finance a small country. Or they start making fake accounts to sign up for the newsletter for the same mail address and start racking up the redeemable codes. Or some sort of combination of the two. This effectively exploits your product and you just wanted to give somebody 10% off on the next pair of shoes they buy.&lt;/p&gt;

&lt;p&gt;Here’s another example. In an effort to increase user engagement, you devise a system of personalized recommendations to the user. Something in the vein of: “We see you like this thing you read, perhaps you would like that other thing that complements it as well?” If you are not careful, the user might get a multitude of such personalized recommendations. So much, in fact, that they start to ignore, or even leave your product altogether. This is definitely undesirable behavior, a direct opposite of what you were trying to achieve.&lt;/p&gt;

&lt;p&gt;But you are a vigilant developer, right? You know the solution for both of these examples I stated, right? Well, sometimes. Sometimes the answer is not as straightforward as you might think. What I’m trying to say is: We’ve all been there. You implement a shiny new feature, release it into the wild, suddenly problems start popping out of the wood-works, and it’s back to the drawing board.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cobra effects at Njuškalo
&lt;/h2&gt;

&lt;p&gt;Throughout the years, we also had our fair share of situations where something that looked good on paper just didn’t work properly when implemented. Since we’re a marketplace platform, we do have features other marketplace platforms have as well.&lt;/p&gt;

&lt;p&gt;For example, on PayProtect, we have a ratings and reviews system. It’s used for building trust with our user base. While planning it, we asked ourselves the 4 W’s:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who can leave/get a review?&lt;/li&gt;
&lt;li&gt;What is the desired outcome of a review left?&lt;/li&gt;
&lt;li&gt;Where can a user leave a review?&lt;/li&gt;
&lt;li&gt;Why should a user leave a review?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While brainstorming the feature, we noticed a possible Cobra effect. If we give a user the possibility to just leave a review, without certain conditions attached, that could lead to bad actors pumping up their reviews and ratings artificially. So we thought on that issue, and came up with a solution. A user can leave a rating and a review for another user only if they have finished a transaction. That means that a seller needs to send the item, the buyer needs to receive the item, the money needs to be paid out to the seller, and then a buyer can leave a review and rating. Also, there is a limit of only one review and rating per transaction. And when we solved the Cobra effect lying in wait, we suddenly had answers to all of our questions.&lt;/p&gt;

&lt;p&gt;As you can see, thinking about Cobra effects can actually speed up your planning stages of a project, so much so that solving it opens up the whole feature to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do we fight the Cobra effect?
&lt;/h2&gt;

&lt;p&gt;Well, first of all, we need to be aware of a possible Cobra effect. We should think about how exploitable a feature is so we can patch up that loophole before it even happens. This mostly comes from experience. The more you develop apps, and the more you learn about them, the more you learn from other developers as well, the more you can think like possible bad actors do, and predict certain behaviors.&lt;/p&gt;

&lt;p&gt;Also, embracing a user-centric design, getting feedback from users on possible pain points can mitigate the risks of a possible Cobra effect. User input is invaluable in these situations because sometimes we’re so wrapped up in all of the stages of a project that we don’t account for natural user behavior until it’s too late.&lt;/p&gt;

&lt;p&gt;Stakeholders need to be notified of the ramifications of such effects, because they impact our reasoning behind implementing a certain feature in a certain way. Being transparent in the development of a certain feature is a must at all times. We should always implement mechanisms for monitoring, measuring and evaluation of our products so we can regularly revisit those results and see the positive or negative consequences of our actions in regards to our users. This way, even if we do have a Cobra effect on our hands, we can pinpoint the exact moment when it started to happen and react accordingly.&lt;/p&gt;

&lt;p&gt;And in the end, we need to consider the ethics behind any given solution. If our products prioritize the well-being of users, in the long run, the Cobra effect may be mitigated entirely.One might say here that even if we do implement all this, bad actors will still find a way to get around all our efforts. They will still find some loophole to exploit. And while that may be true, we must always remain vigilant in monitoring to react as soon as possible. Also, our efforts may have unintended consequences of their own. It’s a neverending process, my friends, but we have mechanisms to fight it, as you can see.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do we have some solutions for the Cobra effect already?
&lt;/h2&gt;

&lt;p&gt;The answer to this question, pure and simple, is yes! The web community constantly works on increasing the ethics and transparency of the web.&lt;/p&gt;

&lt;p&gt;Take GDPR, for example. As one of the solutions for data privacy and protection of users, GDPR is a regulation strengthening the privacy rights of EU residents. By making your product compliant to GDPR, a lot of Cobra effects can be mitigated. The Agile Manifesto, while not an ethics framework in itself, emphasizes principles of responding to change, customer collaboration and iterative growth which in and of itself, serves as a tool in adapting to possible Cobra effects. Constantly, people out there are creating ways to create a safer web for us all. Here at Njuškalo, we try to do the same for our users. That way, we create a better landscape for generations to come.&lt;/p&gt;

&lt;p&gt;This doesn’t mean that we stifle innovation, however. Even with regulations in place, and with keeping the Cobra effect in mind, we can still be innovative and bring much needed value for our customers.In conclusion, all of our actions have consequences, intended or not. While we cannot prevent all of the negative side-effects of our features, we can strive to lessen them by using methods described above. This is the way we create such a successful, sustainable digital product in Njuškalo. So until next time, stay vigilant and remember: the cobra is a devious animal, and you never know when it might strike.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>discuss</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
    <item>
      <title>Bridge to Nowhere: Lessons from Choluteca for Tech Disruption</title>
      <dc:creator>Tomislav Buljević</dc:creator>
      <pubDate>Thu, 25 Jul 2024 07:17:41 +0000</pubDate>
      <link>https://dev.to/tomebuljevic/bridge-to-nowhere-lessons-from-choluteca-for-tech-disruption-nmk</link>
      <guid>https://dev.to/tomebuljevic/bridge-to-nowhere-lessons-from-choluteca-for-tech-disruption-nmk</guid>
      <description>&lt;p&gt;There is a story that I read a while ago, and I often go back to it: it is the story of the Choluteca Bridge, or the “Bridge to Nowhere”, as it might be known. Some of you may already know about it, but for those who don’t, I will share its story with you now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Story of Choluteca Bridge
&lt;/h2&gt;

&lt;p&gt;In Honduras, a country in Central America, there is a river called Choluteca. Unfortunately, Honduras is located in the narrowest part of the piece of land connecting North and South America, making it susceptible to constant hurricanes. In 1996, Honduras decided that a new bridge was needed over the Choluteca River (Puente Sol Naciente or Bridge of the Rising Sun), one that would withstand the damage from storms and hurricanes, as the old one (Puente Choluteca or Choluteca Bridge) had to be frequently repaired. The Japanese company hired for the project constructed a sturdy bridge that was completed in 1998. That same year, a hurricane hit, as it often does in Honduras. The name of that hurricane was Mitch.&lt;/p&gt;

&lt;p&gt;Mitch was a nasty hurricane, producing over 1900 mm of rain over four days, the equivalent of the previous six months of precipitation. The Choluteca River, as a result, flooded the entire region, taking the lives of 7000 people and severely damaging the old bridge crossing it. It also destroyed all of the surrounding access roads. What it couldn’t destroy was the new bridge. Instead, the river changed course. It changed its flow to such an extent that it now ran next to the bridge instead of under it. The bridge itself, with no access roads and the river running next to it, became a bridge over nothing, leading to nowhere.&lt;/p&gt;

&lt;p&gt;So, what does this story have to do with tech? If we take the river as an analogy for the flow of technology, this new bridge as an analogy for a product bridging the gap between the customer and a company, and the hurricane as a single disruptive event changing the landscape of technology, it becomes fairly easy to imagine the consequences of such disruption for today’s products.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disruption? What Is It Good For?
&lt;/h2&gt;

&lt;p&gt;As you can probably already tell, disruption in tech is not necessarily a bad thing. It just means that everything is changing. The evolution of technology, like any evolution, continually shifts toward the optimal solution, which is then widely accepted as the norm. So, in this context, disruption just means “an event after which nothing is the same.”&lt;/p&gt;

&lt;p&gt;Putting the obvious miniaturization of technology as a disruptive event aside, one of the first disruptions was the introduction of the World Wide Web. It changed the way people perceive communication. Suddenly, a computer was no longer reserved only for enthusiasts and businesses; it became available to the general public, leading to the emergence of a new job role – that of a web developer.&lt;/p&gt;

&lt;p&gt;When the first iPhone was introduced at the start of the millennium, it created another new job role, that of a mobile developer. Suddenly, one could access the World Wide Web with their phone and communicate using the screen in their pocket more easily and intuitively than ever before.&lt;/p&gt;

&lt;p&gt;Due to the rise of the mobile phone and the new possibilities of HTML and JavaScript, one particular program was discontinued: Adobe Flash. Once essential for any web multimedia, and the largest victim of disruption up to this point (at least in regards to the Web), it has been supplanted by more secure and efficient technologies like HTML5. Developers specialized in Flash had to upskill in other technologies to stay relevant.&lt;/p&gt;

&lt;p&gt;E-commerce, social networks, dot-com bubble burst, cloud computing, open-source movement, Y2K – all of these changed the way we think about and consume tech, so much so that certain concepts and terms seeped into the mainstream vernacular of the day as well. I remember the hype surrounding Y2K back when I was a kid, and it was a media frenzy that lasted for a couple of days at least.&lt;/p&gt;

&lt;p&gt;The latest disruption is most definitely the emergence of machine learning and generative AI. The consequences are already visible, from different platforms (including Njuškalo) embracing machine learning and predictive algorithms to open-sourcing general, all-purpose AI tools like ChatGPT to enhance our work. And while we cannot predict all the consequences of this latest disruption, we can most certainly agree that it is a disruption and that it is already changing the way we work on our products.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disruptions That… Weren’t?
&lt;/h2&gt;

&lt;p&gt;For all the disruptive events tech has had, there is an almost equal, if not greater number of events that were supposed to change the landscape of tech and announce the Next Big Thing, but they were either ahead of their time or complete dead ends. Dead ends, after all, happen in evolution and go the way of the saber-toothed tiger.&lt;/p&gt;

&lt;p&gt;Google Glass, Google+, iTunes Ping, and Microsoft Zune are some examples of products that completely failed, while QR codes and blockchain are examples of elements that were supposed to be disruptive but ended up not being so and basically adapting themselves to the environment rather than vice versa.&lt;/p&gt;

&lt;p&gt;I feel the need to slide one important caveat into the mix. Blockchain is most definitely an emerging technology that hasn’t been proved to be disruptive thus far, but it has greatly enhanced our vision of the Web, to such an extent that some have started to mention Web 3.0 as a result. As of writing this article, while it has made great strides, it still hasn’t established itself as a major player in the disruption field. It remains to be seen what the future holds in regards to blockchain, though.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hidden Currents of Innovation
&lt;/h2&gt;

&lt;p&gt;Up until this point, I have compared disruptions to hurricanes, reshaping entire landscapes in one fell swoop. But there is another force at play, probably a bit closer to us as developers – gradual change. Picture it as erosion along the riverbanks of technology.&lt;/p&gt;

&lt;p&gt;An example of such a transformation is Web 2.0. From what was once a “read-only” medium, the internet evolved, fueled by participatory culture and interoperability, into the user-immersive medium we know and love today. It most definitely had a larger impact on the consumer vision of the internet and its possibilities than anything that came before it.&lt;/p&gt;

&lt;p&gt;Developers need to be mindful of this gradual change; otherwise, they might find themselves in uncharted waters. And when they embrace this gradual evolution as the norm, they can definitely stay afloat better, even in case of future evolutionary leaps of the tech they work on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Internal Disruptions
&lt;/h2&gt;

&lt;p&gt;It is not only tech that can disrupt a developer’s approach to a product. Internal disruptions can happen as a consequence of business policy. A product you’re developing for a certain use can prove to cater to a specific niche, which then becomes profitable, and as a result, something that started as one thing eventually becomes a different thing entirely.&lt;/p&gt;

&lt;p&gt;Njuškalo started, and thus far has been, a classifieds product, enabling people to place classifieds for the things they want to sell. PayProtect, as a feature of Njuškalo, has been proved to be disruptive, changing the product to a marketplace where you can find anything you might need, basically providing the user with a whole new perspective of the product as a whole. As I write this, people are buying and selling things using PayProtect, completely safely transferring funds and receiving things they bought without too much of a hassle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Resilience
&lt;/h2&gt;

&lt;p&gt;Alright, so we’ve established that disruption happens. There is not much we can do about it. We certainly wouldn’t want to fight against it because if we do, we might just find ourselves and our products obsolete, like a bridge leading to nowhere. So, instead of “building to last,” we should think about “building to adapt.”&lt;/p&gt;

&lt;p&gt;This doesn’t necessarily mean that we should board every hype train we see. After all, as we’ve seen earlier, there are times when even the biggest experts announce a disruption which, at the end of the day, doesn’t actually happen.&lt;/p&gt;

&lt;p&gt;Therefore, a developer needs to have a healthy dose of skepticism. Skepticism drives us to question the tech presented to us, to scrutinize it from different angles, to try to find vulnerabilities to decide if it is a good fit for the product we’re developing. Somewhat paradoxically, the same developer needs to be open to the implementation of such tech, which is a blanket term for being curious about it, being aware that it’s a disruptive element, and “being in the loop,” that is to say, well-informed. These two qualities represent a good foundation for a resilient developer.&lt;/p&gt;

&lt;p&gt;On this foundation we can build other qualities, such as a continuous learning mindset and problem-solving skills. This leads to creativity, which then leads to a unique approach to implementing emerging disruptive tech into a product.&lt;/p&gt;

&lt;p&gt;The skills a resilient developer nurtures and builds upon are useful for future-proofing a product as well. With experience, one can become almost prescient, seeing the different directions a product can take, and preparing an environment that can go in either direction. So, how do we future-proof our product?&lt;/p&gt;

&lt;p&gt;Well, in this context, less is more. By dividing every feature into stages, and having an MVP approach where your feature only does what it’s supposed to, without unnecessary weight, and then by building upon that, thinking about not only the user but the developer experience itself, you can find that your product reaches an almost generic state where everything becomes modular. This modularity leads to proper de-coupling, and this de-coupling leads to a resilient product. You just need to unplug a single feature and plug in a new one, and suddenly you have adapted.&lt;/p&gt;

&lt;p&gt;I’m probably preaching to the choir here. Probably telling you stuff you already know. And yeah, building resilience comes naturally to developers who are at the forefront of a living, breathing product that needs constant evolution.&lt;/p&gt;

&lt;p&gt;At the end of the day, we just need to be aware that disruption is a normal part of our lives, we need to embrace it and prepare for it, and when we do, the possibilities become truly endless.&lt;/p&gt;

&lt;p&gt;And the Choluteca Bridge? In 2003, they reconnected it to the highway, so it found its use.&lt;/p&gt;

</description>
      <category>learning</category>
      <category>development</category>
      <category>softwaredevelopment</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Content Is King for Devs, Too</title>
      <dc:creator>Tomislav Buljević</dc:creator>
      <pubDate>Tue, 21 Nov 2023 13:15:07 +0000</pubDate>
      <link>https://dev.to/tomebuljevic/content-is-king-for-devs-too-418</link>
      <guid>https://dev.to/tomebuljevic/content-is-king-for-devs-too-418</guid>
      <description>&lt;p&gt;&lt;strong&gt;We’ve all heard the sentence “Content is King” in regards to the internet. This was actually the title of a 1996 essay by Bill Gates, which basically predicted how content will shape experiences online, as well as possibilities for monetization. So, for the longest time, it was talked about only in the context of marketing and business aspects of web development.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without high-quality content, we wouldn’t have jobs. Content is what drives businesses to seek out developer expertise. And since Gates’ essay in 1996, content has drastically changed our perspective on what the internet should be. From an obscure concept, the internet has evolved into a behemoth which shapes our very lives through ever-evolving user-contributed content.&lt;/p&gt;

&lt;p&gt;So, why do so many developers actually shy away from it? Throughout the years, I’ve come across sentiments such as “I don’t care about content, I care about code,” or, “What the business posts online is their problem, not mine.” It’s important to note here that not all developers share the same perspective. While some of the best developers I’ve encountered recognize the significance of content in the applications they help create, others have a different focus. The diverse range of viewpoints in our field enriches the discussion, and this is my personal take on the matter.&lt;/p&gt;

&lt;p&gt;In this article, I argue that content is essential for the work we do, as it not only shapes the user experience of an application, but also shapes the developer experience of creating that application.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Content, Anyway?
&lt;/h2&gt;

&lt;p&gt;To be able to think about content, we should know what content is in the first place, right? I asked that question during an internal company event, and I got various answers. But they all seemed to revolve around one idea: “Content is what the user inputs.” And while this definition is valid, I find it too narrow since it essentially ignores other valuable content linked to the primary content, e.g., categories or tags related to news articles on a news portal.&lt;/p&gt;

&lt;p&gt;I used to think that any database entry is defined as content. Or, simply put: anything that can be dynamically changed by any sort of action is content. Other developers tell me that this is too broad of a definition of what falls under content, but I am still not satisfied with it.&lt;/p&gt;

&lt;p&gt;Today, I feel that every piece of information a website or an app shows to the end user is content. Some may be of lower priority, some of higher, but nonetheless, every piece of text, image or video represents content in one way or another.&lt;/p&gt;

&lt;p&gt;With such a broad definition, one might wonder what content is not, then. I would say mostly visual elements such as the layout of a page or the placement of a menu, typography, and the tone of the app itself are not content. They are all a very important part of an app, but they do not constitute content in my book.&lt;/p&gt;

&lt;p&gt;Have you ever found yourself browsing through an app which is really ugly, but due to the quality of its content, you couldn’t stay away? On the other hand, have you ever found yourself browsing an app which looks amazing, but soon became bored due to the lack of good content on it?&lt;/p&gt;

&lt;p&gt;When all is said and done, good content makes or breaks an app, and it’s imperative for developers to have a user-centric approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Content on Njuškalo Works
&lt;/h2&gt;

&lt;p&gt;On Njuškalo, content assumes a multi-faceted form which is created and organized through the collaboration of all participants:&lt;/p&gt;

&lt;p&gt;Registered users, who post classified ads and assign them to the relevant category&lt;br&gt;
Different departments, which are responsible for category allocation, important information snippets (such as the most relevant categories, feature banners, promotions, etc.), and behavior of certain elements on the site&lt;br&gt;
Customer service, which, with the help of our AI, moderates user-generated content&lt;br&gt;
Designers, who determine the overall look and feel of the app, as well as pay attention to the user experience of the site&lt;br&gt;
Developers, who, based on requests from multiple departments around the company, focus on the “how” of displaying and manipulating the content once it is created.&lt;br&gt;
Now, I am not saying that we are special in our content management practices; I am sure that the vast majority of apps today function like this. The point I am trying to make is that given the sheer number of people devoted to the content created, maintained, and organized on our platform, the things developers say about content, such as the ones outlined in the introduction to this article, hardly make sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  Content Matters, but &lt;em&gt;Context&lt;/em&gt; Matters As Well
&lt;/h2&gt;

&lt;p&gt;This is all well and good, I can already hear you say, but we, the developers, are not actually producing content. And you would be right. While we do need to constantly think about content, we should take &lt;em&gt;context&lt;/em&gt; into consideration as well.&lt;/p&gt;

&lt;p&gt;The thing is, we are basically on the fringe of content creation. We’re giving the content context. We’re framing it so that the end user has better information and a better understanding of what they can do with the content they see and how it is presented to them.&lt;/p&gt;

&lt;p&gt;So, the question we should primarily be asking ourselves isn’t “How should I complete the task?”, but more in the line of “What value does my work provide to the end user?”. In an article I previously wrote, I stated that we have a basic responsibility to our customers to have our product work at all times, and there are a lot of moving parts. In this article, I would extend that to include another basic responsibility of ours: to make our product as streamlined and user-friendly as it can be in order to make the customer experience more enjoyable in the long run. I know this sounds like a UX thing, but developers should embrace this mindset as well.&lt;/p&gt;

&lt;p&gt;Let me give you an example. You might think that categorization of something like a classified listing is a no-brainer, right? You have a category, you put your classified in that category, all is right with the world? It is not as simple as that.&lt;/p&gt;

&lt;p&gt;First of all, a category determines the look and feel of a classified. A classified in the Automotive section will not be the same as a classified in the Real Estate section. After all, why should it be? A car is not the same as an apartment. So, if you put your classified in the Automotive section, you’ll get fields for that classified describing the brand of the car, some car features like cruise control, AC, fuel consumption, gearbox type, etc. On the other hand, your Real Estate section will have fields for surface area, number of rooms, location, etc. Filters for each category are different as well. By the way, did I mention we have more than 2,000 categories on Njuškalo?&lt;/p&gt;

&lt;p&gt;Determining a category for a single listing isn’t always straightforward, either. Some items overlap and may be listed in multiple categories.&lt;/p&gt;

&lt;p&gt;And how does one put a classified into a category? I mean, a user just wants to place an ad, don’t they? How do they assign their classified to a category?&lt;/p&gt;

&lt;p&gt;It’s a developer’s job to create the optimal solution which answers all of these questions. But it’s also a developer’s job to challenge ideas produced by the business departments. These challenges are in no way a form of rejection of the business. They represent hurdles which an idea needs to jump over so it could become optimal. So we always need to think about content, and about how to challenge the ideas presented to us from the business perspective in order to achieve a balance between business needs and user experience.&lt;/p&gt;

&lt;p&gt;In the aforementioned example, the questions asked determine the behavior of the app. To place an ad, a registered user needs to select a category first, then input the details of their classified listing. This solves the issue of variable fields for different categories. The system autonomously checks for key attributes of a classified to determine if it is in the correct category or not. If not, it moves the classified to the correct category, and the user might need to re-input some of the details to adjust the listing. This answers the question of determination of category. What about category placement? Well, that one is solved by adding the category property to a classified so it would always know its position. And the end result is most definitely optimal as the user need only click on a button to “Place Ad”, select the category in which they want the classified to be, enter the details prompted by the choice of category, et voilà – intuitive and gratifying for the user.&lt;/p&gt;

&lt;p&gt;As you can see, even something as mundane as categorization can be a problem that is complex to solve. Other apps might have even more use cases for their categorization than what I have described here. By having a user-centric perspective during the development of a solution, developers can methodically and organically reach optimal solutions for all those cases that seem to bother us.&lt;/p&gt;

&lt;p&gt;Here’s another example: since we’re a classifieds site, anyone can post a classified listing. But also, developers are the ones enabling the end user to contact the classifieds poster in different ways: through messages on our site, through phone and e-mail prompts, as well as through the PayProtect system. This all provides context for the users, which is to say, we enable the users to purchase the product and get it delivered to their doorstep more easily than ever before. We also make it possible for users to get more information about the product itself – its condition, location of the product (this is greatly taken into consideration, especially in the Automotive segment), and previous history of the product. This info enables the users to make their choice faster and easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, So Njuškalo Is Actually a Content Management System?
&lt;/h2&gt;

&lt;p&gt;The quick answer is: of course it is! Almost every application is. Every application online has some sort of content. Content is what makes the app, after all. It determines the behavior of the app, and is important not only to the end user, but to the developers themselves. No matter how you approach it, be it statically created on a page or dynamically changed through user input, we’re constantly posting content online. And we’re constantly searching for easier and faster ways to manage it.&lt;/p&gt;

&lt;p&gt;And therein lies the confusion with a lot of developers. When the term “CMS” (Content Management System) is mentioned, the mind usually races to already established and famous platforms like WordPress or Joomla. So developers don’t think of themselves as content managers in one way or another, because they expect to have an established platform if they are acting as such. To them I say, no, whenever you decide on, say, a list of elements to be displayed on a page, you’re managing content, and it might do you well to consider what is most useful for the user who will be using that list more than you.&lt;/p&gt;

&lt;p&gt;I know this might be an oversimplification of the matter. I know you might even disagree with me on it. In fact, feedback and disagreement are encouraged and welcome. But relevance of content for the web is, in my opinion, too large to be ignored and simply dismissed as an afterthought.&lt;/p&gt;

&lt;p&gt;In conclusion, I hope this article has broadened your perspective on what content is, and how important it is for our daily developer operations. And remember, if you catch yourself wondering: “Is my work enhancing the content placed on the app?”, the answer is almost always a resounding yes.&lt;/p&gt;

</description>
      <category>software</category>
      <category>web</category>
      <category>developers</category>
      <category>development</category>
    </item>
    <item>
      <title>Product-oriented vs. agency and why you should care</title>
      <dc:creator>Tomislav Buljević</dc:creator>
      <pubDate>Mon, 21 Aug 2023 12:18:42 +0000</pubDate>
      <link>https://dev.to/tomebuljevic/product-oriented-vs-agency-and-why-you-should-care-4fee</link>
      <guid>https://dev.to/tomebuljevic/product-oriented-vs-agency-and-why-you-should-care-4fee</guid>
      <description>&lt;p&gt;Njuškalo Technology is a company with a history as long as our product itself: Njuškalo, the most prominent Croatian classifieds and marketplace website. In this article, as a developer that has been working for agencies for about nine years and a developer on a single product for the last three, I will try to outline some of the key differences between working on a single product and working on multiple ones.&lt;br&gt;
To preface, I believe that both types of companies have merit in today’s market, but let me tell you a story of how I made the switch and how, even three years later, my passion for our particular little corner of the interwebs is still burning a red-hot flame.&lt;/p&gt;

&lt;h2&gt;
  
  
  In the beginning…
&lt;/h2&gt;

&lt;p&gt;… I wanted to be a developer. No, I am not going to bore you with the sordid details, it’s enough to say that my keyboard was finely tuned for agency work, as well as small projects based on clients’ needs and desires. That is how I stepped into the pond, so to speak, just to realize that what I thought was a pond, was actually a vast ocean of knowledge just waiting to be discovered.&lt;/p&gt;

&lt;p&gt;So, for nine years, I worked for different agencies, dealing with different clients, different needs, and different cases that honed my abilities.&lt;/p&gt;

&lt;p&gt;And then, I got a call from Njuškalo Technology’s HR through the most unbelievable channel: LinkedIn. Setting up a meet, we kind of clicked, and Njuškalo took me into its fold. That’s when my agency work stopped and I started a new chapter of my life.&lt;/p&gt;

&lt;p&gt;Now, that all sounds very dramatic, but I assure you, it wasn’t.&lt;/p&gt;

&lt;p&gt;In the last three years, I guess I had a bit of time to really put things into perspective, so I think I can share my findings with you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is in a project?
&lt;/h2&gt;

&lt;p&gt;First off, let’s define what the word “project” means to agencies and product companies. Basically, for an agency, a project is usually a website. Or an app of some kind. You get a client (I know it’s not easy getting clients but bear with me here), and they have an idea. It is your job to turn their idea into reality. So, for example, a client may ask for a web shop one month, and another can ask for a digital warehouse tracking app the next. Even if, as an agency, you use the same programming language, heck, the same framework, or even content management system, you are bound to get different, very client-specific cases so that those differences pile up, and you get completely different products in the end.&lt;/p&gt;

&lt;p&gt;Also, an agency project can have a maintenance contract on it and you could spend your time fixing the small bugs they report or handling minor change requests from time to time.&lt;/p&gt;

&lt;p&gt;But basically, that is where the project ends. After you finish work for this client, other than maintenance, you don’t need to work for them anymore.&lt;/p&gt;

&lt;p&gt;When you’re working on a single product, your projects mean something completely different. Projects are usually new features, or sets of functionalities made to enhance the product in some way. In that same vein, the latest project I worked on was PayProtect, effectively changing Njuškalo’s whole outlook as a product: it no longer acts only as a classifieds website, it is now a fully-fledged marketplace, enabling people to buy and sell items through the site. So, the team I work in effectively changed what Njuškalo means to a bunch of people, making it a whole lot easier to buy and sell things with just a click of a button.&lt;/p&gt;

&lt;p&gt;And we are not stopping there. Our work on this project is not over. We are continually enhancing it, optimizing it, and giving it love. Because we know that we are bringing value to our users by doing it.&lt;/p&gt;

&lt;p&gt;So, it’s a radically different approach to what a project means, if you see what I mean.&lt;/p&gt;

&lt;h2&gt;
  
  
  The approach to coding is different
&lt;/h2&gt;

&lt;p&gt;I don’t think agency coding has changed much in the last couple of years. You probably use Git, you have a master branch, you code your stuff in a single branch which is based on the task you need to do, you push to your branch, and merge to the main branch when you’re done. Simple as pie. Tests? Well, you would probably really like to write tests, but who has time for those? QA (Quality Assurance) process? Why have a dedicated QA when you can do your testing on the staging server yourself?&lt;/p&gt;

&lt;p&gt;With product work, as developers, we have a bit more time to refine this simple process. When I start working on a task, I do make a branch, I do code the solution to the problem, but I am also required to write tests covering my particular task. My task also goes through a QC (Quality Control) process, where other teammates check on my work and approve it (or disapprove it). After that, somebody else does the QA. Regression is tested automatically for all the critical features. On top of that, a dedicated QA team then checks the whole task, and tests my work thoroughly, trying to break it. Then and only then, if everything checks out, it goes to production and I can brag about it to people.&lt;/p&gt;

&lt;p&gt;Now, this all sounds a bit much, doesn’t it? It’s not actually moving fast, it’s probably (for most of you) moving slower than you might like. But we have a basic responsibility to our customers to have the product work at all times, and there are a lot of moving parts. If one of those parts is out of alignment, the whole ship rocks.&lt;/p&gt;

&lt;p&gt;And personally, I like that my code goes through as many people as it does to reach its destination. It means I am less prone to failure and that our product is as stable as we can make it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping in touch with the times
&lt;/h2&gt;

&lt;p&gt;I cannot truly say how many projects I worked on used cutting-edge technology for their time, only to leave them as is after they’re finished, with the mantra: “Well, if it works, it ain’t broke”.&lt;/p&gt;

&lt;p&gt;See, that’s the deal with agency work. Project after project, you try and use cutting-edge technology, but then you need to do some maintenance, and it all comes crashing down since the project you’re maintaining was finished several years ago, is so many versions old, has things sticking out, and you find yourself working on code written in a standard older than you’re used to. The shiny, new thing keeps eluding you, you find yourself wanting a new project just so you could try to do a better job. There is no time to refactor your old code, there is no chance to do it either, because a new project is just behind the corner, and you’re in a rush to finish the old one.&lt;/p&gt;

&lt;p&gt;At Njuškalo, we might be a bit slower in providing a cutting edge on our project, but we get there. After such an upgrade, everything becomes shiny and new, and since we’re constantly giving love to our project, we have time for refactors. I can sit back and enjoy coding like I wanted to all my life, seeing mistakes I did a while back and fixing them, knowing I’m leaving a better landscape for future developers and my future self.&lt;/p&gt;

&lt;h2&gt;
  
  
  A candle burning on two ends
&lt;/h2&gt;

&lt;p&gt;Let’s say you’re working for a very successful agency, and you have projects piled up to your neck. I argue here that you have a better chance of burning out than you do working on a single product.&lt;/p&gt;

&lt;p&gt;It’s not a matter of different coding styles, it’s a completely different focus shift you experience when you work on multiple different websites, with their own specific issues, with their own needs, and with different versions of technology, which means different approaches to coding, etc.&lt;/p&gt;

&lt;p&gt;With something as stable as a product such as our beloved Njuškalo, we might experience different needs for different projects as well, they might even be very different, but our code and architecture following the same course makes it easier to debug and solve issues without really shifting our focus. There are teams that handle different parts of the product, and one can always rely on their coworkers to help them solve the issue. After all, with as many developers as we have in our company, there’s always someone bound to help, even as a rubber ducky, while we’re solving the thing ourselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  In conclusion
&lt;/h2&gt;

&lt;p&gt;Working on different projects and handling them at the same time can be a daunting task, and it truly sometimes overwhelms you. So, I would definitely say that, when you’re a junior, or even a mid, just learning the trade, working for an agency definitely helps you learn to view a problem from different aspects. This gets invaluable later when you’re working on a product and you face other issues which are similar to something you already worked on previously.&lt;/p&gt;

&lt;p&gt;Working on a product teaches you to slow down as well, and concentrate on quality work which stands the test of time if you apply yourself to it meticulously.&lt;/p&gt;

&lt;p&gt;Reading this back, this whole article sounds like a pitch for developers. Like bragging that we have it good. And maybe, in a way, it is. If you like what you’ve read so far, don’t be afraid to reach out. Perhaps your own journey might be starting right now.&lt;/p&gt;

</description>
      <category>developers</category>
      <category>php</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Some thoughts on the labels we attach to ourselves</title>
      <dc:creator>Tomislav Buljević</dc:creator>
      <pubDate>Fri, 28 Feb 2020 09:18:18 +0000</pubDate>
      <link>https://dev.to/tomebuljevic/some-thoughts-on-the-labels-we-attach-to-ourselves-390m</link>
      <guid>https://dev.to/tomebuljevic/some-thoughts-on-the-labels-we-attach-to-ourselves-390m</guid>
      <description>&lt;p&gt;This is a topic I've been thinking about for a long time now, and my personal opinion on it changed a whole lot since the idea formed. This article is a kind of way to put those thoughts to a single space, and motivate the community to discussion.&lt;/p&gt;

&lt;p&gt;Each time we introduce ourselves in a business environment, we essentially slap a huge label to our foreheads. For example, if I was currently looking for a job, I'd post something like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'm a web-developer with more than 8 years of industry experience. So far, I've been working with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;Javascript&lt;/li&gt;
&lt;li&gt;PHP

&lt;ul&gt;
&lt;li&gt;Symfony framework

&lt;ul&gt;
&lt;li&gt;custom applications&lt;/li&gt;
&lt;li&gt;eZ Publish CMS (now eZ Platform)&lt;/li&gt;
&lt;li&gt;Pimcore&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Laravel

&lt;ul&gt;
&lt;li&gt;custom work&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My work was involved mostly with large distributed systems with complex data models.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, as you can see, I just labeled myself as an experienced backend developer. We do this each time we're on a job interview or a random job posting so we can tell our employers what to expect from us.&lt;/p&gt;

&lt;p&gt;Does an 8-year experience matter? Yes. But I think the last sentence in that paragraph matters even more. Why? Well, what if instead of that, it didn't say anything at all? How would an employer know that I'm the right person for the job? The length of experience is probably less important than the KIND of experience. I know "junior" devs who run circles around "senior" devs with more than 10 year of experience due to their involvement in major projects these seniors never touched before. Yet those "seniors", only because of their title, do not feel obliged to learn from those "juniors". Believe me, those "seniors" are feeling entitled due to their label.&lt;/p&gt;

&lt;p&gt;Also, as you can see, I'm specialized in one thing only. That's a mixed bag. In reality, we all know that PHP is not going anywhere, and in my experience, a switch from one framework to another is not an issue, especially with something as good as Symfony. On the other hand, I could never compete for something like a Python dev, or a Rust dev, or whatever. To people who search for devs using those languages, I'm probably either unemployable or low on the list of others who have more experience than me in those programming languages.&lt;/p&gt;

&lt;p&gt;To those people I say: the KIND of experience matters. What I'm trying to say is that, in the search for quality devs, one should, from time to time, think out of the box. Perhaps the person who just applied for the job has an interest in switching to your tech stack out of a desire to learn. And their past experience, regardless of the technology stack, can help your company in general.&lt;/p&gt;

&lt;p&gt;The point of this thought-piece is that, sometimes, we need to change the way we think in order to progress. &lt;/p&gt;

&lt;p&gt;I'd be happy if we could get rid of at least some of the labels. Learning programming languages is a matter of syntax, mostly. There are always some hurdles you need to pass in order to grasp the nuances of a programming language, of course, but they're all minuscule compared to the general principles of programming you need to apply in your day-to-day development.&lt;/p&gt;

&lt;p&gt;So please, discuss, which labels would you like to see gone and which labels would you like to stay in IT? &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>learning</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Pimcore hidden gems: Tags</title>
      <dc:creator>Tomislav Buljević</dc:creator>
      <pubDate>Thu, 27 Feb 2020 12:57:18 +0000</pubDate>
      <link>https://dev.to/tomebuljevic/pimcore-hidden-gems-tags-5d7p</link>
      <guid>https://dev.to/tomebuljevic/pimcore-hidden-gems-tags-5d7p</guid>
      <description>&lt;p&gt;Pimcore is the leading Product Information Management solution on the market, and it has a bunch of features implemented. It can sometimes be difficult to see all of them, or in fact, use all of them. This article aims to showcase one particular feature developers might use in their arsenal when developing a quality solution using Pimcore as a platform.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://pimcore.com/docs/6.x/index.html"&gt;documentation&lt;/a&gt; is definitely the first stop every aspiring developer should visit. It has a description of all the available features and tools. So when I first started working in Pimcore, the documentation was a powerful ally. And among other tools and cool features presented there, I stumbled upon the &lt;a href="https://pimcore.com/docs/6.x/Development_Documentation/Tools_and_Features/Tags.html"&gt;Tags&lt;/a&gt; functionality. So, let’s dive into this particular feature, shall we?&lt;/p&gt;

&lt;h1&gt;
  
  
  What are Tags, anyway?
&lt;/h1&gt;

&lt;p&gt;The docs tell us that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tags provide a way to create additional taxonomies and classifications for documents, assets and objects.&lt;/p&gt;

&lt;p&gt;By using tags you are able to easily filter Pimcore elements (documents, objects, assets) and keep the additional search criteria to the application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not really a clear definition, huh? Basically, if you’ve ever run into Tags prior to working with Pimcore, you’d know what Tags are, but if you’re new to the term, the documentation doesn’t really give you a lot to go on.&lt;/p&gt;

&lt;p&gt;So, let’s put it this way: A Tag is a small content object, connected to a Document, Object, or an Asset which helps you group data into categories not already in your object tree.&lt;/p&gt;

&lt;p&gt;OK, that’s a bit more on the nose, but still not what we’re looking for.&lt;br&gt;
Even more simplified: A Tag is a keyword which you add to a Document, Object or an Asset which you can then use to easily search and group that content in your application.&lt;/p&gt;

&lt;p&gt;When presented like that, I hope you get a clear idea of what a Pimcore Tag is. In this article, you’ll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how Tags are structured&lt;/li&gt;
&lt;li&gt;how they’re added&lt;/li&gt;
&lt;li&gt;some common usages of Pimcore Tags&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’re also explaining when &lt;strong&gt;not&lt;/strong&gt; to use Tags, as well as giving you some more reading material in case you need to brush up your knowledge. So, read on!&lt;/p&gt;
&lt;h1&gt;
  
  
  Structure
&lt;/h1&gt;

&lt;p&gt;Let’s look at the structure of tags in Pimcore. In your database, Tags are primarily used via two tables, &lt;strong&gt;tags&lt;/strong&gt; and &lt;strong&gt;tags_assignment&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;tags&lt;/strong&gt; table defines the keyword itself, and the position of the tag in the tag subtree.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;tags_assignment&lt;/strong&gt; table defines which tag is assigned to which content object and whether it’s an asset, object, or document.&lt;br&gt;
Simple enough.&lt;/p&gt;

&lt;p&gt;How does it look in the Administration?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iXSPkR1d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/qovpg6dvfuhj2axsyqtq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iXSPkR1d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/qovpg6dvfuhj2axsyqtq.png" alt="Tags menu" width="684" height="672"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your user needs to have the Tag configuration permission checked to view this screen. It shows all the tags available throughout your installation. The tags can have a tree-like structure for better organization so that you can find them more easily when assigning to an object.&lt;/p&gt;

&lt;p&gt;To be able to assign tags in the administration, your user needs to have the Tag Assignment permission checked.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Obn7ircA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/94jbr9g087tz8gpw7a5j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Obn7ircA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/94jbr9g087tz8gpw7a5j.png" alt="Tags assignment" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tag assignment is done on a content object level. So, basically, open the object you need, and assign tags you wish associated with the object itself.&lt;/p&gt;

&lt;p&gt;OK, now that we familiarized ourselves with the structure and assignment, let’s see how we can do it programmatically.&lt;/p&gt;
&lt;h1&gt;
  
  
  PHP API
&lt;/h1&gt;

&lt;p&gt;Let’s say we’d like to list all of the tags for a single object in that object view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Pimcore\Model\Element\Tag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getTagsForElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'document'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$availableKeywords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$tags&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$availableKeywords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$tag&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$tag&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$availableKeywords&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;As you can see, we’re using the &lt;strong&gt;getTagsForElement&lt;/strong&gt; method from the &lt;strong&gt;\Pimcore\Model\Element\Tag&lt;/strong&gt; class. We’re passing the type of object to it (in this case ‘document’), and the id of the element for which we need to display tags. Then, we’re adding the tag ID and tag keyword to the &lt;strong&gt;$availableKeywords&lt;/strong&gt; array which we can then pass to the view to display a keyword on the page.&lt;/p&gt;

&lt;p&gt;How about listing all objects of a single tag?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$objects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Pimcore\Model\Element\Tag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getElementsForTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$availableObjects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$objects&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$availableObjects&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$object&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here, we’re using the &lt;strong&gt;getElementsForTag&lt;/strong&gt; method from the &lt;strong&gt;\Pimcore\Model\Element\Tag&lt;/strong&gt; class to get all objects of a single tag which we then add to the &lt;strong&gt;$availableObjects&lt;/strong&gt; array for further manipulation.&lt;/p&gt;

&lt;p&gt;What if we need to add a tag to an object? Let’s say we have a new tag with keyword ‘keyword’:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$tag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nf"&gt;Pimcore\Model\Element\Tag&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nv"&gt;$tag&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="n"&gt;keyword&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Pimcore\Model\Element\Tag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;addTagToElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;156&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$tag&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;We just created a new Tag, and then used the public method &lt;strong&gt;addTagToElement&lt;/strong&gt; from the &lt;strong&gt;\Pimcore\model\Element\Tag&lt;/strong&gt; class to assign that tag to an object with an ID of 156.&lt;/p&gt;

&lt;p&gt;As you can see, programmatically, it’s really easy to retrieve tags, create tags, and assign them to objects.&lt;/p&gt;

&lt;h1&gt;
  
  
  Usage examples
&lt;/h1&gt;

&lt;p&gt;“Sure”, I already hear you say, “but you haven’t told us anything that we couldn’t get from the official documentation”. Ah, but this is the part of the article where the real fun starts.&lt;br&gt;
So, where can we use Tags?&lt;/p&gt;

&lt;p&gt;Easily enough, one of the answers is - search. If you need to get a list of all the objects using the same keyword, the chunk of code can be the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$tagListing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nf"&gt;Pimcore\Model\Element\Tag\Listing&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nv"&gt;$tagListing&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addConditionParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="no"&gt;LIKE&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$term&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nv"&gt;$objectList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$tagListing&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$taggedObjects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Pimcore\Model\Element\Tag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getElementsForTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$taggedObjects&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$taggedObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$objectList&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$taggedObject&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$object&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getKey&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="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$taggedObjects&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here, we’re searching for all Tags similar to the term a user has input in a search form. Then, we’re merging all the objects found in a single array which we can then manipulate further by displaying, for example, a dynamically generated URL for each object, along with some sort of unique identifier for each object.&lt;/p&gt;

&lt;p&gt;Now you have your search for objects using keywords. How about other usages?&lt;/p&gt;

&lt;p&gt;You can use tags as sub-categories. For example, you created a subtree of Data Objects in Pimcore in the following manner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Products
    |-&amp;gt; Shoes
        |-&amp;gt; Sneakers
            |-&amp;gt; Maxxx Power by Sneakerzilla
            |-&amp;gt; Running Supreme by Sneaker Fanatic
    |-&amp;gt; Clothing
        |-&amp;gt; Sweatpants
            |-&amp;gt; Maxxx Stretch by Sneakerzilla
            |-&amp;gt; Maxxx Comfort by Sneakerzilla
            |-&amp;gt; Running Extreme by Sneaker Fanatic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now say you want to have a single view where you’ll just select a brand, and all of your products for that brand would show, no matter if they’re Sneakers or Sweatpants.&lt;/p&gt;

&lt;p&gt;We’ll create a Tag called Brand, and underneath it, we’ll have “Sneakerzilla” and “Sneaker Fanatic”, respectively.&lt;/p&gt;

&lt;p&gt;So, when we assign “Sneakerzilla” to “Maxxx Power”, ”Maxxx Stretch” and “Maxxx Comfort”, the next time a user visits the page for Brand selection, and they select “Sneakerzilla” as their preferred brand, they’ll get exactly what we need them to get without a big change to the Data Model or the Subtree we already established previously.&lt;/p&gt;

&lt;p&gt;The code for this is largely the same as the code for the search, only you’re required to create a simple route which will then only display the single tag by passing it a tag id. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\HttpFoundation\Request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\Routing\Annotation\Route&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// …&lt;/span&gt;

&lt;span class="cm"&gt;/*
* @Route(“/tag/show/{id}”, name=”show_tag”)
* @param Request $request
* @param $id
*/&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;action&lt;/span&gt; &lt;span class="nf"&gt;showTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;$id&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$tag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Pimcore\Model\Element\Tag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$taggedObjects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Pimcore\Model\Element\Tag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getElementsForTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$tag&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;taggedObjects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$taggedObjects&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;So, we fetched a single Tag by its ID, we extracted all of the tagged objects and passed them to the view for display on the page. We also passed the Tag to the view since we’ll need some stuff from the Tag itself to display (for example, name).&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s take things to an extreme
&lt;/h2&gt;

&lt;p&gt;Say you need to create a customer feedback functionality in your Pimcore installation. You already have a form with input fields which stores some sort of a message into your database. And now, you need to categorize all of the user requests a certain way. For example, Support, Sales, and, let’s say, Employment.  And you need to create a mailing feature to send mail to one of those based on what was selected.&lt;/p&gt;

&lt;p&gt;You can easily create three tags, which you can then display as a Select in the Feedback form. When the Feedback form is submitted, after the form object itself has been created, assign it the selected Tag. After a Tag has been assigned, you can trigger an event in which you can send mail to the office responsible for handling such requests. Read the Addendum to this article for more on Tag events.&lt;/p&gt;

&lt;p&gt;Later, when the office in question asks for a list of all messages received, you can easily create an export of such messages using Tags to filter them out quickly.&lt;/p&gt;

&lt;p&gt;How about matching user behavior with their most viewed pages?&lt;br&gt;
You could create a Targeting rule which takes into consideration how many times a Customer visited a single page tagged with a certain Tag, then assign the same Tag to that Customer. When the Customer visits the page next time, you can show all of the documents and objects tagged with that term.&lt;/p&gt;

&lt;p&gt;As you can see, Tags, even though they’re small and unassuming, can be a powerful tool in your toolbox while you develop.&lt;/p&gt;

&lt;h1&gt;
  
  
  When not to use Tags
&lt;/h1&gt;

&lt;p&gt;Of course, one should always keep in mind the paradigm we so often use: “Use the right tool for the right job”. In the previous usage examples, we’ve hopefully shown that Tags can be powerful, but they have their limitations.&lt;/p&gt;

&lt;p&gt;Always keep in mind that a Tag is nothing more than a keyword, and it can only go so far. It’s limited in its usage since there is only ever three key pieces of information you actually store in it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Its position in the Subtree&lt;/li&gt;
&lt;li&gt;The relation to different content (Data Objects, Assets and Documents)&lt;/li&gt;
&lt;li&gt;The keyword itself&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The position in the Subtree is important for more complex Tag structures since we can then divulge the siblings of a Tag (for example, when you need to show Tags similar to the current one).&lt;/p&gt;

&lt;p&gt;Also, Tags cannot be expanded upon using conventional methods, and they actually &lt;strong&gt;shouldn’t&lt;/strong&gt; be. We need to use them carefully since the Data Model is an ever-changing thing.&lt;/p&gt;

&lt;p&gt;So, if at any point during the development of your project you might find that you need more from a Tag besides these three key pieces of information, maybe it's better to use a Data Object instead.&lt;/p&gt;

&lt;p&gt;One more thing to consider is that a Tag in Pimcore is not easily translatable to other languages. For different languages, you might need to open up a new subtree of keywords.&lt;/p&gt;

&lt;p&gt;This, however, should not discourage you from trying Tags in your project. You might actually find that, by using Tags, your whole Data Model becomes less cluttered and more accessible to others.&lt;/p&gt;

&lt;h1&gt;
  
  
  Addendum: Tag Events &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;As of the time of the writing of this article, there are no Events available for adding or removing Tags. The Events exist only for copying content (to add the copied content the same tag), and for removing assets (to remove all tags from the removed asset).&lt;/p&gt;

&lt;p&gt;But, adding such an Event shouldn’t be too difficult.&lt;/p&gt;

&lt;p&gt;You would want to create an Event, which would then trigger any time you create a Tag in a particular place of your installation. Then, a designated event dispatcher would dispatch such an Event, on which you can then hook your Event Listener. The Listener would then send an email.&lt;br&gt;
For further information, I suggest you read more about &lt;a href="https://symfony.com/doc/current/components/event_dispatcher.html"&gt;Symfony’s Event Dispatcher&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I hope that this article has been of use to you and that you might find yourself using Tags more in the future.&lt;/p&gt;

&lt;p&gt;Until next time,&lt;/p&gt;

&lt;p&gt;Tomislav Buljević&lt;/p&gt;

&lt;p&gt;(Images courtesy of &lt;a href="https://pimcore.com/docs/6.x/Development_Documentation/Tools_and_Features/Tags.html"&gt;Pimcore documentation&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;article originally published at &lt;a href="https://factory.hr/blog/pimcore-hidden-gems-tags"&gt;https://factory.hr/blog/pimcore-hidden-gems-tags&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>pimcore</category>
      <category>symfony</category>
      <category>php</category>
      <category>learning</category>
    </item>
    <item>
      <title>A recipe for success as a Pimcore developer</title>
      <dc:creator>Tomislav Buljević</dc:creator>
      <pubDate>Tue, 23 Jul 2019 10:31:44 +0000</pubDate>
      <link>https://dev.to/tomebuljevic/a-recipe-for-success-as-a-pimcore-developer-3n8k</link>
      <guid>https://dev.to/tomebuljevic/a-recipe-for-success-as-a-pimcore-developer-3n8k</guid>
      <description>&lt;p&gt;In this article, you’ll find tips from an experienced Pimcore developer with more than 7 years in developing frontend and backend technologies and deep expertise with Pimcore. We’ll start with an introduction to &lt;a href="https://factory.hr/services/pimcore-development"&gt;Pimcore development&lt;/a&gt; and 5 things you should adhere to while developing apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Pimcore?
&lt;/h2&gt;

&lt;p&gt;Pimcore is an open-source custom experience management with all digital asset management. It allows you to connect multiple websites or platforms in one place where you can boost your business and be more productive.&lt;/p&gt;

&lt;p&gt;There are 4 main advantages of using Pimcore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understanding customers with a need for B2B &amp;amp; B2C platforms&lt;/li&gt;
&lt;li&gt;Easy searching, editing, and publishing items with Master Data Management&lt;/li&gt;
&lt;li&gt;Scalable CMS for any type of content and business&lt;/li&gt;
&lt;li&gt;Merging and consolidating data with Digital Asset Management&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to be a successful Pimcore developer
&lt;/h2&gt;

&lt;p&gt;Every developer in the world has faced this challenge: You have a framework which is at the top of its game, and you choose a CMS made in that framework or for that framework. You install it (more or less) successfully, and you’re looking at the interface, and the PHP API. Scratching your head, you’re thinking: &lt;em&gt;Where/How should I start?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It’s a natural part of learning, and in this article, we intend to help you better understand one particular system on one particular framework: Pimcore, based on the Symfony framework. Hopefully, you’ll be able to find your way around it after this read.&lt;/p&gt;

&lt;p&gt;One more thing before we start: This article will NOT cover coding examples. The PHP API for Pimcore is well documented &lt;a href="https://pimcore.com/docs/6.x/Development_Documentation/"&gt;here&lt;/a&gt;. Instead, I’m going to outline some key concepts you’ll need to embrace to truly be successful in developing web applications on Pimcore.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Change your way of thinking
&lt;/h2&gt;

&lt;p&gt;Content management systems typically have a difficult time separating dynamic content from static pages, and indeed even media assets from content itself. This can present a problem when you’re working with a web application managing a lot of content with some media interspersed. Even such a thing as a daily-updated blog can sometimes be difficult to traverse if we’re talking about taxonomy, reusable images, content linked to other content, etc.&lt;/p&gt;

&lt;p&gt;Pimcore has a clear separation of three different types of content you can create: Documents, Assets and Data Objects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documents
&lt;/h3&gt;

&lt;p&gt;Documents represent your static pages. In this area, you cover the Landing pages, different content snippets, and basically everything you need to be permanently displayed on that URL. It also represents your sitemap for the site.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assets
&lt;/h3&gt;

&lt;p&gt;Every chunk of media you place on your site is located here. When you upload an image to an article, for example, it is stored in this area and linked to your article using Pimcore’s API. As reusability is a key factor, you can always access the images and media stored here and link them to other chunks of content you might have.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Objects
&lt;/h3&gt;

&lt;p&gt;This is the dynamic custom content on your page. It has a structure based on folders, and you will put data which changes often in this area. For example, if your Pimcore installation is an e-commerce solution, the Products will be located here.&lt;/p&gt;

&lt;p&gt;As you can see, when we say “Change your way of thinking”, we mean that the structure of this system is largely different from other solutions which can be found, making your content easily searchable and traversable. Creating a web application as a Pimcore developer will mostly consist of inputting data in one of these main areas, and you need to know where to put what.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Chunk-ize and reuse
&lt;/h2&gt;

&lt;p&gt;Since it enables you to make a practically infinite number of different custom data types fast, Pimcore gives you an option to change the way your content creates the big picture. For example, say you have created a custom data type which has 5 selections. You later realize that you need to use that same selection in another data type. Pimcore allows you to reuse your existing selection options on several different content types.&lt;/p&gt;

&lt;p&gt;But let’s take things even further. Now you realize that there are not only 5 choices in your selection. There are 50. And that number can get larger. Now it makes sense to create a custom datatype which will store your key and value into the database, and make your selection options available across multiple content types. Pimcore handles these scenarios very efficiently.&lt;/p&gt;

&lt;p&gt;We’ve covered reuse, but what about chunk-izing? Well, chunk-izing simply means that you can (and certainly will) separate your content into smaller chunks which store groups of data connected logically. And which will always store the same data throughout the page. That way, you can create a view which has not one, but many small chunks of content all connecting logically, like Legos.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Mind your triggers
&lt;/h2&gt;

&lt;p&gt;Let’s say you inherit a project that someone else already started working on. You try to test things out, but something deep inside the kernel throws an error. You need to debug, so you open the file that appeared to cause the error. To your surprise, nothing in the file seems to be causing the problem. What could it be?&lt;/p&gt;

&lt;p&gt;When it comes to debugging, the hardest to find issues can be caused by event listeners, in particular triggers that somebody wrote and forgot about. So, when moving into an existing project be sure to deep dive into the code, and see the big picture. Try to get in the mindset of the person who wrote the code and what they were trying to achieve – that trigger is probably there for a reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Don’t reinvent the wheel
&lt;/h2&gt;

&lt;p&gt;Pimcore has lots of built-in features right out of the box, and because Pimcore is built on top of the Symfony framework, chances are that there’s already a bundle for almost any feature you need. At the very least you’ll probably find a PHP library to help develop such a feature.&lt;/p&gt;

&lt;p&gt;When I started off with Pimcore, I needed to implement a QR Code feature for my application. The QR Code needed to be based on a URL, and it needed to be stored onto my system somehow. I was wracking my brain trying to find a proper QR Code library, then thinking of how to store it. Then a random search in the docs told me there was already a QR Code feature built-in! I could easily create an asset in Pimcore using the native PHP API to store the data, which made the whole thing easy.&lt;/p&gt;

&lt;p&gt;Before you start custom coding something, don’t forget to arm yourself with the docs and Google, and try to find an existing solution. Be it a Symfony bundle, or a Pimcore feature, it probably exists somewhere. And only when you’re positive it doesn’t, try to create it on your own.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Don’t be afraid
&lt;/h2&gt;

&lt;p&gt;Pimcore is massive. It can seem overwhelming. And it’s ultimately a developer’s tool – you cannot just install it and get a ready-made web-page. You’ll need a bit of time and patience to learn it well.&lt;/p&gt;

&lt;p&gt;Also, don’t be afraid to break your application. The best developers learn from their own mistakes. Don’t be afraid to ask questions. The larger community of Pimcore developers is forthcoming and willing to help. Be sure to create an account on Pimcore’s forum, &lt;a href="https://talk.pimcore.org/"&gt;https://talk.pimcore.org/&lt;/a&gt;. Your issues will be solved quickly.&lt;/p&gt;

&lt;p&gt;Be sure to express issues and concerns you might have with this system. It makes for improvements, either in your own way of thinking or in the codebase of Pimcore itself. And finally, don’t hesitate to explore. Pimcore has a bunch of features, and you can use them all to solve problems you didn’t even know you had until you stumbled onto them.&lt;/p&gt;

&lt;p&gt;And above all, don’t be afraid to become a Pimcore developer! It’s a gratifying experience, believe me.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;article originally published at &lt;a href="https://www.sourceseek.com/a-recipe-for-success-with-pimcore/"&gt;https://www.sourceseek.com/a-recipe-for-success-with-pimcore/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>pimcore</category>
      <category>symfony</category>
      <category>php</category>
      <category>learning</category>
    </item>
    <item>
      <title>Checking out interest for topics</title>
      <dc:creator>Tomislav Buljević</dc:creator>
      <pubDate>Sun, 26 May 2019 15:00:10 +0000</pubDate>
      <link>https://dev.to/tomebuljevic/checking-out-interest-for-topics-3mm5</link>
      <guid>https://dev.to/tomebuljevic/checking-out-interest-for-topics-3mm5</guid>
      <description>&lt;p&gt;Hello everyone. I am a developer. Doing it on a daily basis. Switched jobs recently and made a transit from eZ Platform to Pimcore. So I was wondering... Would the community at large like to read about some practices I stumbled upon in my experience? Basically, I'd be writing about Symfony and stuff. So... How about it? Share your thoughts, please. &lt;/p&gt;

</description>
      <category>php</category>
      <category>coding</category>
    </item>
  </channel>
</rss>
