• Tinylytics for Micro.blog v2.1 Released

    TinylyticsHeaderArt

    Hot on the heels of uptime monitoring on Tinylytics, I’m stoked to share that my Tinylytics for Micro.blog plug-in has been released as a 2.1 version to take advantage of it.

    This release adds the following:

    1. The ability to use a Hugo shortcode to add a Page View Counter in a post without changing any site template files. This will display the actual views of a single post, rather than overall hits -- which can still be shown as a footer embed.
    2. The ability to show your site uptime embedded in the global custom footer of your Micro.blog site without changing any site template files.

    Note: Uptime monitoring is a paid feature of Tinylytics. You'll need to have a paid account for uptime stats to show via this plugin.

    You should see a new version available in your site plug-ins area soon.

    For more details about using the plug-in, see the README on the Github project page.

    If you have any other questions or find a bug, contact me through any of the methods in my site footer below.

  • Tinylytics for Micro.blog 2.0 Release

    TinylyticsHeaderArt

    I’m happy to share that my Tinylytics for Micro.blog plug-in has been released as a 2.0 version. This release adds the following:

    1. A complete refactor/rewrite of the tracking code for better performance.
    2. The ability to use Hugo shortcodes to add Kudos and Hit Counter in a post without changing any site template files.
    3. The ability to add a Hit Counter embed in the global custom footer of your Micro.blog site without changing any site template files.

    You should see a new version available in your site plug-ins area soon.

    For more details about using the plug-in, see the README on the Github project page.

    If you have any other questions or find a bug, contact me through any of the methods in my site footer below.

  • Tinylytics for Micro.blog Updated to 1.0.6

    TinylyticsHeaderArt

    Fresh on the heels of new Tinylytics.app updates, my Tinylytics for Micro.blog plug-in has been updated to take advantage of the new Kudos feature introduced in the latest release. If you look at your installed site plug-ins, you should see an update available as 1.0.6.

    This release adds a checkbox to show Kudos along with the ability to set a custom label. See the project README on Github for more information.

    Tinylytics config

    Special thanks go out to @vincent for simply being an all-around awesome dude too.

  • New Plugin: Tinylytics for Micro.blog

    TinylyticsHeaderArt

    I published my very first Micro.blog plugin today: Tinylytics for Micro.blog. You can find it in the Micro.blog plugin directory.

    If you’re using Vincent Ritter’s awesome web analytics platform Tinylytics, this plugin is for you. Rather than copying and pasting a line of Javascript, you simply enter your unique site id which can be copied from your site page once the plugin is installed.

    Tinylytics plug in options

    There’s an option to toggle the “Display Hits” option too.

    To show hits on your site, you’ll need to modify your Micro.blog theme to make the hits show up. The easiest way to accomplish this might be to add code in the footer of your theme’s design area (Design > Edit Footer):

    Footer edit

    See this Tinylytics help article for more information on displaying hits on your site.

    The plugin source can be found at this Github repo: https://github.com/jimmitchell/Tinylytics-for-Micro.blog.

    Email me with questions or any issues you find.

  • Debunking the Myth of "Better Means Different"

    Change is inevitable in today’s world as technology advances, industries evolve, and societies progress. The idea of “better means different” has gained popularity, suggesting that to improve, one must embrace change and pursue new and unconventional approaches. While this idea may seem appealing, it is important to critically analyze both the pros and cons of this notion to better understand its implications.

    The Pros of "Better Means Different"

    1. Innovation and Progress: Embracing change and seeking different approaches can lead to innovation and progress. Trying new methods, technologies, and ideas can drive improvements in various aspects of life, from business and science to personal growth. For example, the introduction of smartphones revolutionized the way we communicate, work, and access information, leading to significant progress in many areas of society.
    2. Flexibility and Adaptability: Embracing the idea that "better means different" encourages flexibility and adaptability. Being able to adapt to new situations and approaches is crucial for success. Embracing change can help individuals and organizations remain agile and respond effectively to shifting circumstances, enabling them to stay ahead of the curve.
    3. Diversity and Inclusion: Embracing different perspectives and approaches can foster diversity and inclusion. When we acknowledge that "better means different," we open ourselves to diverse ideas, cultures, and people. This can lead to more inclusive decision-making, problem-solving, and collaboration, ultimately resulting in better outcomes. Research has shown that diverse teams tend to be more innovative and perform better in problem-solving tasks.

    The Cons of "Better Means Different"

    1. Resistance to Change: Not everyone is comfortable with change, and embracing the idea that "better means different" can be challenging for some. Change can be disruptive and unsettling, especially when it requires abandoning familiar methods or systems. People may resist change due to fear of the unknown, loss of control, or increased workload. This resistance can hinder progress and innovation if not addressed effectively.
    2. Risk of Failure: Pursuing different approaches may involve taking risks, and not all risks lead to success. Trying new methods or ideas may result in failure or setbacks, which can be demoralizing and costly. Fear of failure can deter individuals or organizations from exploring different approaches, leading to a reluctance to change and a preference for familiar methods.
    3. Disruption and Inefficiency: Constantly pursuing different approaches can lead to disruption and inefficiency. Frequent changes can disrupt established processes, systems, and relationships, resulting in confusion, frustration, and decreased productivity. Moreover, constantly changing approaches may not allow for sufficient time to evaluate and optimize the effectiveness of each approach, leading to suboptimal outcomes.

    The Bottom Line

    The notion of "better means different" can be a double-edged sword. While embracing change and pursuing different approaches can lead to innovation, flexibility, and diversity, it may also encounter resistance, involve risks of failure, and result in disruption and inefficiency.

    It’s crucial to carefully consider the context, potential benefits, and drawbacks of different approaches to achieve meaningful progress. Striking a balance between stability and change is essential, and organizations and individuals must critically evaluate the implications of this notion in their pursuit of improvement.

    As the saying goes, “change for the sake of change” may not always lead to better outcomes, and a thoughtful, strategic approach is necessary to achieve sustained success in today’s ever-evolving world.

  • Living the Simple Life: Chill, Declutter, and Embrace the Beauty of Simplicity

    Are you feeling overwhelmed by life? Do you find yourself juggling multiple tasks, drowning in notifications, and feeling like there’s never enough time in a day? If so, you’re not alone. In today’s fast-paced world, simplicity has become a luxury that many of us crave. The good news is that living a more simple life is totally achievable, and it can bring you a sense of peace, contentment, and fulfillment.

    To help you simplify your life, here are some practical tips I’ve found are easy to fold into your daily routine:

    1. Declutter your space: Start with the physical clutter. Take a look around you and identify items that no longer serve a purpose or bring you joy. Donate, sell, or recycle them to create a more minimalist and organized environment. From my own experience, a tidy space can do wonders for your mental clarity and overall well-being.
    2. Prioritize what matters: It's time to get clear on your priorities. Identify what truly matters in life and let go of the unnecessary commitments and obligations that don't align with those values. Learn to say "no" to things that drain your time and energy, and make room for activities and relationships that bring you joy and fulfillment.
    3. Unplug and be present: In today's digital age, it's easy to get caught up in the never-ending scroll of social media, emails, and notifications. Take regular breaks from screens and be fully present in the moment. Engage in activities that allow you to be fully present, such as reading a book, going for a walk, or having a face-to-face conversation with family and friends.
    4. Simplify your routines: Streamline your daily routines to minimize decision fatigue. Simplify your morning and evening routines, meal planning, and daily tasks to create more time for activities that truly matter to you. Having a simple and structured routine can help you feel more organized and focused through the day.
    5. Connect with nature: Nature has a way of reminding us of the beauty and simplicity of life. Spend time in nature, whether it's taking a hike, camping, or simply sitting in a park. Disconnect from technology and allow yourself to fully immerse in the tranquility and serenity of the natural world.
    6. Cultivate meaningful relationships: Invest time and energy in building deep and meaningful relationships. Focus on quality over quantity when it comes to relationships. Prioritize spending time with people who bring joy, support, and positivity to your life.
    7. Practice gratitude: Shift your mindset to one of gratitude and appreciation for what you have in your life. Take time each day to reflect on the blessings and simple pleasures of life. Gratitude can help you cultivate a positive outlook and find contentment in the present moment.
    8. Pursue meaningful experiences: Instead of chasing after material possessions, focus on creating meaningful experiences that enrich your life. It could be traveling to a new place, trying a new hobby, or volunteering for a cause you're passionate about. These experiences can bring lasting joy and fulfillment that material possessions often can't.
    9. Reflect and reassess regularly: Living a simple life is an ongoing process. Regularly reflect on your priorities, possessions, and commitments to ensure they align with your values and bring true fulfillment. Reassess and make adjustments as needed to stay on track with your journey towards simplicity.

    Simplicity looks different for everyone. It’s not about following a rigid set of rules or standards, but rather about finding what works best for you and your lifestyle. Embrace the process of simplifying your life at your own pace, and don’t be afraid to make adjustments along the way.

    Living a more simple life isn’t about depriving yourself of things, but rather about creating space for what truly matters to you. It’s about living intentionally, with a focus on the present moment and the things that bring you joy and fulfillment. So, take a step back, look at your priorities, and take one simple step to start simplifying your life today. You might be surprised at how much more fulfilling and meaningful life can be when you embrace the beauty of simplicity.

    Are you ready to simplify your life? Start by decluttering a physical space, prioritizing your time and energy, or being present in the moment. Reflect on your values and priorities, and make conscious choices that align with them. Embrace the beauty of nature, cultivate meaningful relationships, and practice gratitude.

    It’s a journey, not a destination. Be patient with yourself and enjoy the process.

  • Personal Blogging vs. Social Media: Why Blogging is Making a Comeback

    The world of social media transformed the way we interact and share content online. Platforms like Facebook, Instagram, and Twitter gave us quick and easy ways to share our thoughts, images, and videos with the world. But what about personal blogging? Is there still a place for it in today’s digital age?

    Personal blogging first became popular in the early 2000s, with platforms like Blogger, LiveJournal, and WordPress. These platforms gave people a space to express themselves, share their stories, and connect with like-minded individuals. However, with the rise of social media, personal blogging began to lose its appeal. Social media offered more convenience, instant gratification, and the ability to connect with others easily.

    But in recent years, personal blogging has made a comeback. Why? Because personal blogging offers something that social media platforms don’t.

    First, personal blogging gives you complete control over your content. Unlike social media, where algorithms decide which posts to show and which to hide, personal blogs give you the power to create a unique brand and present yourself in the way you choose.

    Second, personal blogging allows for longer-form content. On social media, posts are limited in length and can be easily overlooked by users scrolling through their feeds. Personal blogs provide a space for more in-depth writing, which can attract readers who are looking for more than just a quick update.

    Finally, personal blogs can provide significant benefits for businesses. By maintaining a blog, businesses can improve their search engine optimization (SEO), build a loyal audience, and increase their credibility in their field.

    So why is personal blogging better than closed-wall social media? For one, personal blogs offer freedom of expression. On social media, content that goes against platform policies can be removed without warning. Personal bloggers can express their opinions and beliefs without the fear of censorship.

    Second, personal blogs are less algorithmic. Social media platforms use algorithms to determine which content users see. This means that even if a post is excellent, it may not be seen by a large audience. Personal blogs, on the other hand, allow for more organic discovery of content.

    Finally, personal blogs are more authentic. Social media platforms have become a breeding ground for fake accounts and paid promotions. Personal blogs provide a space for genuine expression and real connections.

    To sum it up, personal blogging still has a place in today’s digital age. While social media has its benefits, personal blogging provides a space for more control, creativity, and authenticity. Whether you’re blogging for personal expression or business benefits, there’s no denying the unique advantages that personal blogging offers.

  • A Better AppleScript Password Generator

    As I continue to explore ChatGPT’s AppleScript code generation capabilities, I fed it a password generation script I came up with years ago and asked it to make it better.

    The results were impressive.

    My original script didn’t have error-checking or user bailout points. ChatGPT was smart enough to add them for me, along with some other smart “decisions” when it came to copying out the generated password. I did have to make a few edits for correctness.

    This is the result, which I’ve opted to start using instead of my old script:

    property allowedCharacters : {33, 35, 36, 37, 38, 42, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 61, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122}
    property givenPasswordLength : 21
    
    repeat while true
        try
            set givenPasswordLength to text returned of (display dialog "Enter desired password length:" with title "Password Generator" default answer givenPasswordLength)
            set givenPasswordLength to givenPasswordLength as integer
            if givenPasswordLength is not greater than 0 then error "Please enter a valid positive integer."
            exit repeat
        on error errMsg
            display alert "Error" message errMsg as warning
            return -- added to ensure proper script exit
        end try
    end repeat
    
    repeat while true
        try
            set generatedPassword to generatePassword()
            set dialogResult to (display dialog "New generated password:" & return & return & generatedPassword with title "Password Generator" buttons {"Refresh", "Copy", "Cancel"} default button "Refresh" cancel button "Cancel")
            if button returned of dialogResult is "Copy" then
                set the clipboard to generatedPassword as string
                exit repeat
            else if button returned of dialogResult is "Cancel" then
                exit repeat
            end if
        on error errMsg
            display alert "Error" message errMsg as warning
            return -- added to ensure proper script exit
        end try
    end repeat
    
    on generatePassword()
        set generatedPassword to ""
        repeat givenPasswordLength times
            set randomCharacterPosition to random number from 1 to count allowedCharacters
            set generatedPassword to generatedPassword & (ASCII character item randomCharacterPosition of allowedCharacters)
        end repeat
        return generatedPassword
    end generatePassword

    As always, this improved script works great with FastScripts.

  • Minimalism vs. Essentialism: Understanding the Difference and How It Impacts Your Life

    In today’s fast-paced and consumer-driven world, many people are seeking ways to simplify their lives and focus on what truly matters. Two popular concepts that often come up in these discussions are minimalism and essentialism. While they may seem similar on the surface, they are distinct ideologies with different approaches to living intentionally. In this blog post, we will delve into the differences between minimalism and essentialism and explore how each of them can impact your life in unique ways.

    Minimalism: Less is More

    Minimalism is a lifestyle and design movement that advocates for simplicity and the idea that less is more. It encourages the removal of unnecessary possessions, distractions, and clutter from your life, with the goal of creating more space, time, and freedom for what truly matters. Minimalism is often associated with a minimalist aesthetic, characterized by clean lines, neutral colors, and a focus on functionality.

    Essentialism: The Pursuit of What Truly Matters

    Essentialism, on the other hand, is a philosophical concept that emphasizes the pursuit of what truly matters and the intentional allocation of resources, such as time, energy, and attention. Essentialism encourages focusing on the essential few and eliminating the non-essential many, in order to make meaningful contributions and live a purpose-driven life. Essentialism is about discerning what truly matters to you and aligning your choices with your values and purpose.

    Understanding the Differences

    While minimalism and essentialism share some similarities, they have distinct differences in their principles and approaches. Here are some key differences:

    1. Approach to Possessions: Minimalism focuses on decluttering and reducing possessions to the essentials, often with a minimalist aesthetic. Essentialism, on the other hand, encourages evaluating possessions based on their true value and purpose in your life, rather than simply decluttering for the sake of minimalism.
    2. Focus on What Matters: Minimalism tends to focus on simplifying physical possessions and external distractions, whereas essentialism places a strong emphasis on clarifying and pursuing what truly matters to you, aligning your choices with your values and purpose.
    3. Time and Energy Management: Essentialism emphasizes intentional allocation of time, energy, and attention to the essential few, while minimalism primarily focuses on possessions and decluttering physical space.
    4. Mindset: Minimalism often emphasizes the "less is more" mindset, whereas essentialism emphasizes the discernment and pursuit of what truly matters to you.

    How Minimalism Impacts Your Life

    Minimalism can have a positive impact on your life in various ways:

    1. Reduced clutter and distractions: Minimalism can help you declutter your physical space and reduce distractions, leading to a more organized and focused life.
    2. Increased mindfulness: By being intentional about the possessions you keep and the choices you make, minimalism can help you cultivate mindfulness and present moment awareness.
    3. Enhanced aesthetics: Minimalism often results in a clean and minimalist aesthetic, which can bring a sense of calm and tranquility to your living spaces.

    How Essentialism Impacts Your Life

    Essentialism can also have a significant impact on your life:

    1. Clarity and focus: Essentialism helps you gain clarity about what truly matters to you and enables you to focus your time, energy, and attention on those essential things, leading to increased productivity and fulfillment.
    2. Alignment with values and purpose: Essentialism encourages aligning your choices with your values and purpose, helping you live a more meaningful and purpose-driven life.
    3. Better decision-making: Essentialism prompts you to discern and prioritize what truly matters, which can lead to better decision-making and more intentional choices in various areas of your life.

    Conclusion

    In a nutshell, minimalism and essentialism may seem similar, but they have distinct differences in their principles and approaches. Minimalism focuses on decluttering possessions and simplifying external spaces, while essentialism emphasizes discernment, alignment with values and purpose, and intentional allocation of resources. Both can have a positive impact on your life, such as reduced clutter, increased mindfulness, enhanced aesthetics, clarity, focus, alignment with values and purpose, and better decision-making.

    Incorporating elements of both minimalism and essentialism into your life can be a powerful combination. By decluttering your physical space and being intentional about what truly matters to you, you can create a more focused and meaningful life. Aligning your choices with your values and purpose can help you live a more intentional and purpose-driven life.

    Whether you choose to embrace minimalism and simplify your possessions or practice essentialism to align your choices with your values and purpose, it’s about finding what works best for you. It’s not about strict rules or ideologies, but rather about creating a life that aligns with your true values and purpose. Embrace the journey of self-discovery and intentional living, and see how minimalism and essentialism can positively impact your life in unique and meaningful ways.

    So, go ahead and declutter your physical space, be intentional about what you allow into your life, and align your choices with your values and purpose. Embrace the minimalist mindset of “less is more” and the essentialist philosophy of pursuing what truly matters. Create a life that is focused, intentional, and meaningful - a life that is uniquely yours!

  • Living with Meniere's Disease: My Personal Journey

    This post is written based on my own struggles as someone diagnosed with Meniere’s Disease. It took years to get a proper diagnosis because the condition is so rare.

    What is Meniere's Disease?

    As someone who has been living with Meniere’s Disease for more than a decade, I know firsthand the challenges and impact it can have on daily life. Meniere’s Disease is a chronic vestibular disorder that affects the inner ear, leading to episodes of vertigo, tinnitus, hearing loss, and a feeling of fullness or pressure in the ear. These episodes can be unpredictable and disabling, making it difficult to carry out routine activities and affecting overall quality of life.

    The Symptoms I Experience

    One of the most distressing symptoms of Meniere’s Disease for me is vertigo. During a vertigo attack, I feel a spinning sensation, accompanied by severe dizziness, imbalance, and nausea – often with vomiting. The attacks can last for hours or even days, leaving me feeling exhausted and disoriented. The hearing loss and tinnitus that accompany Meniere’s Disease also add to the challenges. The hearing loss can range from mild to severe and may be temporary or permanent. The tinnitus, which is a constant ringing, buzzing, or roaring in the ear, can be bothersome and impact my concentration and sleep.

    What It's Like to Have Meniere's Disease

    Living with Meniere’s Disease can be emotionally and physically draining. The unpredictability of vertigo attacks and the impact on daily activities can lead to frustration, anxiety, and depression. The hearing loss and tinnitus can also affect communication and social interactions, leading to feelings of isolation and withdrawal. Additionally, the fear of having a vertigo attack in public or at work can create challenges in managing work responsibilities and engaging in social activities.

    Strategies for Dealing with Meniere's Disease

    Over the years, I have learned to develop strategies to cope with Meniere’s Disease and manage its impact on my daily life. Here are some strategies that have helped me:

    1. Working closely with a healthcare provider: It is crucial to work closely with a healthcare provider who specializes in vestibular disorders, such as an otolaryngologist or a neurotologist. They can provide accurate diagnosis, prescribe appropriate medications, and recommend other management strategies tailored to my specific needs.

    2. Making lifestyle adjustments: I have made several lifestyle adjustments to minimize triggers for vertigo attacks, such as avoiding triggers like caffeine, sodium, alcohol, and stress. Regular exercise, sufficient sleep, and a healthy diet have also helped me manage Meniere's Disease symptoms better.

    3. Managing stress: Stress is a major trigger for vertigo attacks with me, so I prioritize stress management techniques such as deep breathing, meditation, and exercise. I also engage in activities that I enjoy and find relaxing, such as reading, spending time in nature, and practicing hobbies.

    4. Building a support system: Having a supportive network of family, friends, and healthcare providers has been invaluable in coping with Meniere's Disease. They provide emotional support, understanding, and practical help when needed.

    5. Using assistive devices: Eventually, I'll need to use assistive devices, such as hearing aids, to manage the hearing loss associated with my Meniere's Disease. These devices will help improve my communication abilities and overall quality of life.

    Conclusion

    I hope this glimpse into my personal experience with Meniere's Disease and the strategies I use to manage its symptoms helps you. Despite the challenges, I have found ways to cope with Meniere's Disease and maintain a fulfilling life. It requires self-care, proper medical management, and support from loved ones and healthcare providers.

    By using strategies such as lifestyle adjustments, stress management, it is possible to manage the symptoms and improve overall quality of life. If you suspect that you or a loved one may have Meniere’s Disease, it is important to seek medical evaluation and guidance for proper diagnosis and management. Remember that you are not alone, and there are resources available to help you cope with Meniere’s Disease.

    References:

    1. Mayo Clinic. (2021). Meniere's Disease. https://www.mayoclinic.org/diseases-conditions/menieres-disease/symptoms-causes/syc-20374910

    2. Vestibular Disorders Association. (n.d.). Meniere's Disease. https://vestibular.org/understanding-vestibular-disorders/types-vestibular-disorders/menieres-disease

    3. National Institute on Deafness and Other Communication Disorders. (2021). Meniere's Disease. https://www.nidcd.nih.gov/health/menieres-disease

    4. American Academy of Otolaryngology-Head and Neck Surgery. (2021). Clinical Practice Guideline: Meniere's Disease. https://www.entnet.org/content/clinical-practice-guideline-menieres-disease

    5. Meniere's Society. (n.d.). Coping with Meniere's. https://www.menieres.org.uk/information-and-support/coping-menieres

    6. Balance & Dizziness Canada. (n.d.). Meniere's Disease. https://balanceanddizziness.org/menieres-disease/

    7. Meniere's Research Fundation. (n.d.). Meniere's Disease: Strategies for Coping. https://menieresresearch.org.uk/resources/strategies-for-coping/

  • A Better AppleScript to Compress Files or Folders

    A while ago, I created an AppleScript that allows you to compress files and folders by simply dropping them onto the applet. One of the readers left a comment asking for a way to achieve the following tasks:

    1. Select a folder from Finder.
    2. Store the folder name as "x".
    3. Compress all files and sub-folders within the folder "x", including their paths.
    4. Rename the resulting zip file as "x.zip".
    5. Delete all the files that were used to create the zip file.
    With the help of ChatGPT, I was able to come up with a solution to this challenge, which can be a great way to manage archives if you're into that sort of thing.

    I must admit that ChatGPT did a decent job in generating the AppleScript, but there were some bugs that I had to fix manually. Nevertheless, it’s both scary and exciting to have a tool that can generate usable code.

    As always, you can run this script using FastScripts from your menu bar for quick and easy access.

    -- choose files or folders to archive since AppleScript can't seem to allow both at once...
    set archiveOption to button returned of (display dialog "Archive files or folders?" buttons {"Cancel", "Folders", "Files"} default button 3)
    
    -- now let's choose what we want to archive...
    if archiveOption is "Files" then
    	set selectedItems to choose file with prompt "Select files you want to compress:" with multiple selections allowed
    else if archiveOption is "Folders" then
    	set selectedItems to choose folder with prompt "Select folders you want to compress:" with multiple selections allowed
    else if archiveOption is "Cancel" then
    	return
    end if
    
    -- set the array of files or folders selected...
    if the selectedItems is {} then
    	return
    else if (selectedItems count) is equal to 1 then
    	set thePathFilename to the quoted form of POSIX path of (selectedItems as string)
    else
    	set thePathFilename to {}
    	repeat with i from 1 to (selectedItems count)
    		copy (quoted form of POSIX path of (item i of selectedItems as string)) & space to end of thePathFilename
    	end repeat
    	set thePathFilename to thePathFilename as string
    end if
    
    -- coerce a date string for the archive name
    set currentDate to current date
    set yearStr to year of currentDate as string
    set monthStr to (month of currentDate as integer) as string
    if length of monthStr = 1 then set monthStr to "0" & monthStr
    set dayStr to day of currentDate as string
    if length of dayStr = 1 then set dayStr to "0" & dayStr
    set currentDateStr to yearStr & "-" & monthStr & "-" & dayStr
    
    -- next, let's name our archive, which defaults to "Archive" & the currentDateStr we just coerced
    set archiveName to text returned of (display dialog "Enter a name for your archive:" default answer "Archive " & currentDateStr buttons {"Cancel", "OK"} default button 2)
    
    -- then, let's choose where to save the archive and compress it with the shell "zip" command
    set archiveFile to POSIX path of (choose folder with prompt "Choose a location to save the archive:")
    do shell script "cd " & quoted form of archiveFile & " && zip -r " & quoted form of archiveName & ".zip " & thePathFilename
    
    -- finally, let's delete the files we just archived if we decide we don't need them around anymore.
    set deleteFiles to button returned of (display dialog "Do you want to delete the original files?" buttons {"Yes", "No"} default button 2)
    set deleteOption to false
    if deleteFiles is "Yes" then
    	set deleteOption to true
    end if
    if deleteOption is equal to true then
    	if selectedItems is not {} then
    		set fileList to {}
    		repeat with itemPath in selectedItems
    			set end of fileList to quoted form of POSIX path of itemPath
    		end repeat
    		
    		repeat with fileItem in fileList
    			do shell script "rm " & fileItem
    		end repeat
    	end if
    end if
  • Conquering Commitment Chaos: Saying No, Setting Priorities, and Taking Charge of Your Life!

    In our busy lives, it’s easy to let things pile up and overcommit ourselves, all under the guise of importance. We may find ourselves saying yes to tasks or commitments that we should have said no to, driven by our ego or fear of disappointing others. But it’s crucial to recognize when we’re stretching ourselves too thin and take steps to lighten the load. Here are some strategies to help you learn to say no and guard your relationships and health.

    Consider Who's Affected

    When faced with a new commitment, take a moment to consider who will be affected the most. It’s easy to neglect important relationships, such as family, when we’re overwhelmed with other responsibilities. Reflect on the impact your commitments are having on your loved ones and your own well-being. Remember that nurturing these relationships should be a priority, and it’s okay to say no to other commitments to protect them.

    Can Someone Else Do It?

    Let go of your ego and acknowledge that you’re not the only person who can handle a particular task or commitment. There may be others who are equally or even more qualified to take it on. Consider delegating or sharing the workload with someone else. It’s also okay to allow others to be challenged and grow by taking on tasks that may be outside their comfort zone.

    Is it Truly Important?

    Question the importance of the commitment. Sometimes, we assume that a task is crucial to others when in reality, it may not be as important as we think. Talk to the person who asked for your help and clarify their expectations. They may have alternative solutions or be willing to find someone else to take over. Open communication can prevent misunderstandings and unnecessary burdens.

    Hold Your Ground

    Saying no may not always be easy, and it may result in disappointment or hurt feelings. However, it’s crucial to prioritize your well-being and be honest with others about your limitations. Share how the commitments are affecting your life and relationships in a respectful and compassionate manner. Most people will understand and appreciate your honesty. However, some may not, and that’s okay. Hold your ground and stay true to your decision, knowing that it’s the best choice for you.

    Learning to say no and lighten your load is a process that requires self-awareness and assertiveness. It’s important to guard your relationships and health closely and make intentional choices about your commitments. Remember, saying no doesn’t make you less capable or caring; it’s a sign of self-care and healthy boundaries. So, reflect on your commitments, be willing to delegate or say no when needed, and learn to listen to your heart instead of your ego. Your well-being and relationships will thank you in the end.

  • iPhone Minimal Dockless Wallpaper for iOS

    As someone who ascribes to a minimalist mindset and hates superfluous design, it’s always bugged me that Apple feels iOS needs a dock outline for icons at the bottom of the home screen.

    With the four icons I choose to keep on my home screen, I find it visually distracting to have an outline around them. So, I decided to make a minimal iPhone and iPad wallpaper that will cancel out the dock when using iOS dark mode, which is my preferred mode.

    This is what my iOS 16 minimalist setup looks like for lock and home screens:

    iOS 16 Screenshots

    I use the lock screen widgets for Fantastical and Things to add an event or task quickly, which has been very handy.

    If you’re running iOS 16 and like the look of my setup, you can download the wallpaper, add it to your photos and then set as your wallpaper. Just keep in mind you need to be running dark mode on your iOS device.

  • It's Your First Dreamforce. What Should You Expect?

    Exciting! It’s your very first Dreamforce!

    You’re eagerly anticipating being part of the magic. I bet you’ve already checked out other blogs to prepare for this moment. Well, here are some recommendations from me to make your Dreamforce experience even more memorable.

    Comfortable Shoes

    Make sure to wear shoes that your feet are already used to and comfortable in. Don’t buy new shoes to wear for the first time at Dreamforce. You may even want to bring two pairs of super-comfy shoes if possible. Trust me, your feet will thank you. Walking is a big part of Dreamforce (I logged over 40 miles last year!), and by the end of the first day, your feet will be tired. Having an extra pair of shoes can help reduce foot fatigue and keep you feeling refreshed.

    Also, bring extra socks and change them during the day. It’ll make a difference, I promise.

    Crowds, Chaos, and Pandemonium

    Rumor has it that Salesforce reduced the number of attendees this year compared to last, but still, be prepared for crowds and chaos. The entire Dreamforce campus will be packed, with most people looking at their mobile devices to figure out where to go next. So, pack your patience along with those comfy shoes.

    Some people will be friendly, and some won’t. That’s just how it is. But deciding to be friendly and approachable will go a long way in enjoying the whole experience.

    Remember to smile at others and strike up a conversation with a stranger or two while waiting in line. You never know who you might meet by chance.

    Don't Overload Your Schedule

    During my first year at Dreamforce, I filled my schedule with back-to-back sessions I wanted to attend, but I barely made it to half of them. Give yourself plenty of time to get to your next session. Keep in mind the crowds, chaos, and pandemonium, not just on the streets but also in the hotels where sessions are held.

    Twenty minutes to get from one place to another is not enough unless the sessions are in the same hotel. Give yourself enough time to get there and find a good seat.

    Also, leave some empty time in your schedule to wander around areas you’re interested in. The Admin, Developer, or Expo halls have a lot to see. Having some free time to stroll through them might lead to unexpected opportunities to learn something new or meet someone interesting.

    Stay Hydrated and Well-Fed

    It’s easy to skip meals or forget to drink water at Dreamforce. Bring high-protein or complex carb, non-sugary snacks to keep hunger at bay. It’ll help you retain the patience you’ll need throughout the event.

    Staying hydrated will also reduce headaches and fatigue. There will be water stations all over the place, so make sure to use them!

    Don't Carry a Laptop

    Unless you absolutely need to have your laptop with you, leave it at the hotel. I carried mine during my first Dreamforce and only used it once. It ended up being more of a burden than a tool.

    Instead, carry an analog journal to take notes, or have a good note-taking app on your phone. Our team will be using Quip to share session notes with each other this year. The app is so good that it has a permanent place on my phone’s home screen.

    Don't Be Afraid of Your Heroes

    If you happen to come across someone from the Salesforce community who inspires you, take the opportunity to introduce yourself to them. Be polite and respectful of any ongoing conversations they may be in, but by introducing yourself, you could open the door to a friendship or future opportunities.

    The community heroes are heroes for a reason - they enjoy sharing their knowledge and experiences with others. So don’t be shy, strike up a conversation and make connections. You might just end up with a mentor or a new friend.

    Take Breaks and Pace Yourself

    Dreamforce can be overwhelming with its non-stop activities, sessions, and events. It’s important to take breaks and pace yourself to avoid burnout. Find a quiet corner or a park within the Dreamforce campus to take a breather and relax.

    You can also take advantage of the Dreamforce App to plan your schedule and set reminders for breaks. Don’t push yourself too hard trying to do everything. Remember, quality over quantity.

    Explore the Expo Hall

    The Dreamforce Expo Hall is massive, with hundreds of vendors showcasing their products and services. Take the time to explore and engage with the vendors that align with your interests or business needs.

    Be sure to have your badge scanned at vendor booths for a chance to win prizes and giveaways. It’s also an excellent opportunity to learn about new Salesforce technologies and solutions that can benefit your organization.

    Have a Plan B for Sessions

    Sometimes, the sessions you want to attend might be full, or the lines might be too long. Always have a backup plan. Identify alternative sessions or activities in case your first choice doesn’t work out.

    You can also check out the Dreamforce recordings after the event to catch up on sessions you missed. And don’t forget to engage on social media using hashtags to join the conversation and stay updated on the latest happenings.

    Have Fun and Embrace the Experience

    Dreamforce is not just about learning and networking; it’s also about having fun and enjoying the experience. Take advantage of the numerous parties, concerts, and special events happening throughout the week.

    Attend the Dreamfest concert, participate in the 5K run, or simply hang out at the various lounges and relaxation areas. Make the most of your time at Dreamforce by immersing yourself in the unique atmosphere and energy of the event.

    In conclusion, your first Dreamforce can be an overwhelming but exciting experience. Be prepared for crowds, stay hydrated and well-fed, plan your schedule wisely, and don’t forget to have fun. Embrace the opportunity to learn, network, and connect with fellow Salesforce enthusiasts. Make memories that will last a lifetime, and most importantly, enjoy the journey!

  • The Ant Mound

    One of my earliest childhood memories still haunts me to this day. I was just a three-and-a-half-year-old boy living with my mother, stepfather, and newborn sister in an old house in the middle of the desert in Lancaster, California. My mother was preoccupied with taking care of my baby sister, so I was often left to my own devices.

    One day, I stumbled upon an ant mound in the open area behind our house. Intrigued, I decided to befriend the ants by sitting down next to their mound. Little did I know, these were not your ordinary ants - they were large, red and black ones with powerful jaws. As soon as I sat down, the ants swarmed me, biting me all over my body.

    The pain was excruciating, and I panicked. I tried to brush the ants off, but they kept coming. In a frenzy, I stripped off my clothes and ran naked towards the house, screaming for my mother. When I burst into the room where she was nursing my sister, she was shocked to see her little boy covered in red welts, crying uncontrollably.

    My mother quickly tended to my wounds, squishing the remaining ants in my hair and applying ointment to soothe the bites. Her care helped calm me down, but the experience left a lasting impression on me. My mother found the whole ordeal hilarious, but for me, it was a traumatic lesson learned.

    Since that day, I’ve developed a fear of ants. Even the smallest ones make me jittery, and I can’t shake off the feeling of panic when I see them crawling on me. I’ve never sat on an ant mound again, knowing the consequences all too well. My mother and I reminisced about that incident many times over the years, and it’s a memory that still lingers with me, half a century later.

  • Memorable Cigarettes

    Almost fifty years have passed, and I can still vividly recall the first time I lit a cigarette. I was just a seven-year-old boy, living on a farm in rural Colorado with my mother, step-father (if you could call him that), and half-sister. There were no kids my age nearby to play with, so I often found myself engaging in activities that little boys should not be doing. I had stolen a pack of my mother’s Kool Menthol 100s and a pack of matches, and I thought I could smoke just like the adults in my life.

    I sneaked outside and hid behind the juniper trees, feeling a sense of rebellion and curiosity. I opened the pack, took out one of the long cigarettes, put it between my lips, struck a match, and lit up, taking a puff just like I had seen the grown-ups do. To my surprise, I didn’t find the taste repulsive. In fact, I kind of liked it. I remember the sensation of menthol on my tongue, the slight burn in my throat, and feeling strangely grown up.

    As I grew older, I experimented with smoking occasionally, but it never really stuck. I would smoke here and there but would eventually lose interest. That changed when I met Tracy, a boy my age who had just moved into the neighborhood. He was already a pack-a-day smoker, and one summer evening, he offered me a Marlboro Red from his hard pack box, explaining that soft packs were not cool. I started taking him up on his offers and before I knew it, I was smoking every day, even bumming cigarettes from friends whenever I could.

    Then came the moment I realized I was hooked: I wanted to smoke even when I was alone. My mother, in her unique parenting style, decided to buy cigarettes for me openly rather than have me hide my habit. She hoped I would come to hate smoking and quit, but that didn’t quite go as planned. By the time I was sixteen, I was a confirmed pack-a-day smoker. It wasn’t about being cool like other kids; it was about feeding my nicotine addiction. Twelve years passed in a blur of cigarettes, until I met Pam.

    I remember our first date like it was yesterday. We were running across a busy street in Santa Monica, heading to a club to see a band. In the middle of the street, my hard pack of Marlboro Lights fell from my shirt pocket with a loud thud. I quickly picked them up, but when we reached the sidewalk, Pam told me, “I don’t date people who smoke.” It felt like a punch to the face, but it was a wake-up call I needed.

    From that moment on, I didn’t light up on any of our dates or any day after that. Pam became my best friend, and we’ve been married for 25 years now. I made the choice to quit smoking because of her, and I’m proud to say that I haven’t touched a cigarette since before we were engaged. I remember many cigarettes I smoked throughout my life, but thanks to someone special, I can’t recall the very last one. And for that, I’m eternally grateful.

  • Start Somewhere

    Do you ever find yourself using up every excuse in the book to avoid doing something you’ve been putting off? I know I do. I’ve been running this blog for nearly 14 years, yet I only have 11 posts to show for it. That’s less than one post per year, and the newest one is over a year old. I used to write more frequently, but like many artists, I ended up trashing most of my work because I felt like it wasn’t good enough. Looking back, I regret that decision.

    Writing has always been a passion of mine. I love the process of putting words down, then rearranging them to communicate my ideas. When I’m in the flow, the words just come out effortlessly, and I feel like I’ve created something that has a life of its own.

    However, a few years back, I made a fatal mistake. I started modeling my writing after what other people were doing, trying to find my own voice. But because it wasn’t truly my voice, I began to doubt the value of what I had to say. This led to a severe case of writer’s block that lasted for years. It was painful to even think about writing, and I only managed to publish three posts in 2018, and they were a struggle.

    To fill the void of creativity, I found myself procrastinating by endlessly tweaking my WordPress theme. I became obsessed with making it pixel perfect and starting over from scratch multiple times. I’ve written and tweaked more CSS code than I care to admit, and my site theme is now practically everything I’ve ever imagined in my head. There’s not much more room for improvement, if any.

    So, what do I do now?

    I’ve realized that it’s time to stop procrastinating and just write. It doesn’t have to be perfect, and my writing will improve with practice. It doesn’t have to be profound or impart deep wisdom to the reader. I simply need to start getting the thoughts in my head onto the page.

    The best place to start is here and now, so I’ve decided to begin again.

    What about you? What have you been putting off? Is now the time for you to start afresh too? Remember, perfection isn’t necessary, just taking that first step towards your goal can make all the difference.

  • Dealing with Digital Distractions: How I Regained Control of My Life

    In today’s fast-paced world, distractions abound, and most of them come from our electronic devices. It’s disheartening to see people with their faces buried in their phones, seemingly disconnected from the world around them. Personally, I reached a breaking point with digital distractions and decided to take action. Here’s what I did to regain control of my life.

    I Started by Removing Useless Apps from My Phone

    At one point, I had more than four screens of apps on my iPhone, and I know many people who have even more. It became overwhelming, and I often forgot where an app was among the numerous screens of mostly unused apps. I realized that I had turned organizing my apps into a game, constantly shuffling them around in search of the perfect arrangement.

    So, I decided to purge. I deleted the time-wasting “social” apps from my phone without hesitation. If I wanted to spend time on Facebook, I would intentionally make time for it. Now, I rarely check Facebook, and I’ve even reduced my “friend” list to only include people I actually know. I also experimented with moving the remaining apps I didn’t absolutely need to a folder on the second home screen. If I used an app frequently, it earned a promotion back to the first home screen. After a month, I ended up with just 16 apps on my first screen, including the four essential ones in the dock.

    For apps that I didn’t touch after two months, I removed them from my phone completely. I realized that I could always download them again if I needed them. This approach has helped me stay focused when using my phone, and I now regularly evaluate my home screen to remove or demote apps that don’t serve a purpose.

    I Set Most App Notifications to Badge Only

    To further reduce distractions, I set most app notifications on my phone to badge only. No sounds, vibrations, banners, or alerts that can disrupt my concentration. I check my apps on my own schedule, not dictated by notifications. Of course, there are exceptions to this rule. Phone and Messages notifications are necessary for communication, and I also allow notifications for my task management and calendar apps. However, I turned on “Do Not Disturb” mode between 10 pm and 6 am to have uninterrupted time for sleep and focus in the morning.

    Breaking free from the constant need to check notifications was challenging at first, but with time, I found myself picking up my phone less frequently and being more productive throughout the day. It’s liberating to not be tethered to my phone all the time.

    I Set Limits on Device Use

    As a family, we decided to set limits on when and where electronic devices are acceptable. For example, we have a strict rule of no phones at the table during meals, whether at home or in a restaurant. During family gatherings, we put away our devices in pockets or purses, allowing us to connect with each other face-to-face. We may use phones for taking photos, but we remind each other to stay present and not get lost in our devices. This approach has helped us be more mindful and present in our interactions.

    These are some of the strategies I’ve employed to combat digital distractions and regain control of my life. It’s a continuous process, and I sometimes slip up, but overall, I’ve found that I’m more aware of my device usage and more engaged with the world around me. If you’re also looking to reduce digital distractions, I encourage you to give these strategies a try. You might be surprised by the positive impact it can have on your life.

  • Unlocking the Power of Saying No: How It Can Transform Your Life

    Saying no can be hard, but it’s a powerful tool that can bring positive change in our lives. It’s not about weakness; it’s about strength, prioritization, and self-care. When we have the courage to say no, we stop spreading ourselves too thin and make more time for what truly matters. Here are some key areas where saying no can have a profound impact:

    1. Saying No to Overcommitment: It's easy to say yes to every new project or opportunity that comes our way, but it can lead to burnout and neglect of our personal priorities. By saying no to excessive commitments, we can create space for what truly matters, such as spending time with our families, pursuing our passions, and taking care of our well-being.

    2. Saying No to Unhealthy Habits: We all have bad habits that hold us back from being our best selves. Whether it's emotional eating, procrastination, or wasting time on unproductive activities, saying no to these habits allows us to break free from their grip and focus on healthier behaviors that support our well-being.

    3. Saying No to Distractions: We live in a world filled with distractions, from constant notifications on our devices to external demands on our time and attention. Learning to say no to these distractions allows us to stay focused, be present in the moment, and be more productive.

    4. Saying No to Negative Influences: Toxic relationships, negative environments, and draining situations can weigh us down and hinder our growth. Saying no to these influences is essential for protecting our mental and emotional well-being and creating a positive environment that nurtures our growth.

    5. Saying No to Procrastination: Procrastination is a common challenge that can rob us of our time and productivity. Saying no to the temptation to delay important tasks allows us to be more disciplined, focused, and effective in achieving our goals.

    Saying no takes effort and practice, but the benefits far outweigh the challenges. It empowers us to make conscious choices, prioritize what truly matters, and create a more fulfilling life. So, let's be courageous and embrace the power of saying no to unlock our full potential and live a more intentional and meaningful life.

  • Rediscovering Wonder: Breaking Free from the Cycle of Empty Pursuits

    Life is cyclical, and we often find ourselves chasin new things only to lose interest in them. We’ve become addicted to instant gratification and caught up in the pursuit of material possessions, but what if we intentionally slowed down and rediscovered the wonder of the world around us?

    As children, we played and marveled at the world with curiosity. We listened to our inner voices without distractions. But as adults, we get caught up in the busyness of life, chasing after dreams and possessions, constantly connected to our smart devices. But are we truly content? Is our soul at peace?

    If there’s even a hint of hesitation in our answer, it’s time to step back and reflect on the bigger picture. Our time on this Earth is limited, and it would be tragic to reach the end with regrets. Maybe today is the day to stop spinning cycles on unnecessary things that don’t truly matter.

    The choice has always been ours. Let’s choose to slow down, rediscover wonder, and live a more fulfilling life, one that aligns with our true desires and brings us genuine contentment. It’s time to break free from the cycle of chasing after empty pursuits and find what truly fulfills us. The power to choose is in our hands.

  • Passing Your Salesforce ADM201 Certification Exam

    I passed the Salesforce ADM201 certification exam today. It’s been a five-year road to get here. From the first week I began working with Salesforce, I decided attaining certification was something I wanted to pursue.

    Now that I’ve done it, I thought it might be good to share the things that helped me be successful with those looking to do the same.

    Know Your Stuff

    Your success or failure pretty much boils down to this… You’ve got to know your stuff or it’s never going to happen.

    The Salesforce ADM201 certification exam is not a walk in the park. You’ll never pass it by just reading the online help, or taking online practice tests and studying flash cards — most of which are badly outdated, or just plain wrong.

    You’re going to need to be familiar with just about every area of Salesforce and how it actually works — where and how you can do something, and where and why you can’t do something else.

    This means getting a developer org and configuring it just like you would if you were doing it for your day job or a client. Be creative in your approach. Try doing things you’ve never done. Try to break it. Enter real data and learn how it flows through the system from a Campaign to a converted Lead to a resolved Case.

    Learn it, live it, be it…

    Do everything in your power to wrap your head around the big picture of what Salesforce does and totally understand it. That’s what being a good admin is all about anyway — knowing what can or can’t be done.

    Study With a Group

    I can’t stress this one enough.

    My employer was kind enough to purchase a year of Premiere Plus Support in order to provide me the online courses to pursue certification, and I did all 60+ hours of both the ADM201 and DEV401 trainings. I learned a lot from it, but it wasn’t until I joined a study group that the learning really sank in.

    Collaborating with a group of your peers introduces fresh ideas, which could give you a completely different perspective about a topic. That, in turn, leads to other moments of discovery. If you’re serious about earning a certification, I suggest you find others who are as committed as you to passing your exam.

    I joined the Salesforce Certification Study Group[efn_note]Thanks to link rot, this site is no longer available.[/efn_note] in the Salesforce Success Community. Deepa Patel and the others who volunteer with the group have worked hard to develop a successful curriculum with a high passing rate for those who are committed enough to make it to the end. It doesn’t cost any more than your time and effort, plus the $200 to register for your Salesforce ADM201 certification exam, which you’re going to spend anyway.

    Once you’re accepted into the private group, watch what goes on in the Chatter feed for a while, then when signups for the next round of sessions are announced, join the one that best suits your geographical region.

    Make the Time

    Okay. You’ve been accepted into the study group. But if you aren’t totally serious about earning your certification, you’ll never be successful. Period. You’ve got to want it to happen. If you don’t give studying the attention it needs, you can forget about passing, and may as well stop reading now.

    Make it what you think about when you’re sitting in traffic, brushing your teeth, or taking a shower. Turn off the TV for a couple hours each night and learn something new about Salesforce instead. Choose to become obsessed for a while.

    If you end up joining the certification study group, make time to do the work you’re supposed to do before the next session — every single week. Commit to the 15 weeks the group is going to require from you. Be ready to demo your work for the online sessions. Know exactly what you did, why you did it, and have a reason for it. I promise you’ll learn incredible amounts if you commit to working this way.

    Be Real with Yourself

    Be 100% honest with yourself. Ask yourself “Am I really ready to pursue certification?” If you’ve only been working with Salesforce a few months, it’s going to be a tough row to hoe, even with the help and support of a study group — who may not be too keen helping you along while studying themselves.

    Being part of a group requires commitment. People are depending on you to have ideas that could be different than theirs. Are you really ready to commit to a group of 6–12 people for 15 weeks, and collaborate with them? Are you really ready to do 5 to 8 hours of homework each week? It’s going to take serious sacrifice.

    If you’re not ready, then wait until you are. You have a better chance of succeeding if you do. By joining the study group without enough experience, chances are you’ll fall behind fast, which is going to discourage you. Don’t set yourself up to fail. Be ready.

    Use Good Resources

    I mentioned the online tests and flash cards earlier. Don’t rely on them at all. Salesforce adds lots of new features at each release. Flash cards and tests from the Spring ’11 release are full of misinformation now. If you rely on them to know your stuff, you might not know much at all.

    There is one good resource I’ll personally endorse, and that’s John Coppedge’s Certified On Demand.

    I joined while John was developing the site, but would have no hesitation spending the $40 lifetime membership that he’s asking for now. It’s a good resource that’s kept current. The questions he’s developed are quite similar to the real test (but not actual questions, and are just a little easier).

    Consider supporting John’s efforts and buying a lifetime membership. Use Certified On Demand as a supplement to studying with the Salesforce Certification Study Group. It helped me be confident I was ready when I started doubting myself.

    The only other resource you need now is to watch the Dreamforce Get Started on the Certified Administrator Credential[efn_note]Link rot got this one too. Too bad, it was a great resource.[/efn_note] workshop video. It provides solid advice for being ready, how to take the Salesforce ADM201 certification exam, and knowing what you’re walking into.

    Taking Your Exam

    You’ve scheduled your test, and now it’s time to go take it.

    There’s only one thing to be said… Know that you know what you know. If you’ve worked hard in the Salesforce Certification Study Group, you’re ready to pass. Walk into the exam knowing that fact.

    When you sit down to begin, take a minute to breathe and relax. Then start your exam using the techniques you learned from the workshop video. Before you know it, you’ll be waking out of the testing center as a Salesforce Certified Administrator.

  • AppleScript to Compress Files and Folders

    I had the need to select several folders at once in the Mac OS Finder and zip them up as individual archives. This AppleScript to compress files and folders was the solution I came up with.

    The script compresses each item selected into its own archive, and works with both folders and files.

    tell application "Finder"
        set theList to selection
        repeat with i from 1 to (count of theList)
            set theItem to (item i of theList) as alias
            set itemPath to quoted form of POSIX path of theItem
            set fileName to name of theItem
            set theFolder to POSIX path of (container of theItem as alias)
            set zipFile to quoted form of (theFolder & fileName & ".zip")
            do shell script "zip -jr " & zipFile & " " & itemPath
        end repeat
    end tell
    

    Download the source here.

    As always, you’ll get the best results when used with FastScripts by Red Sweater Software.

  • Salesforce Flows, Visualforce and Context

    I was asked to find a solution for our field reps that would simplify the process of adding a completed task to their activities when they visited one of our retail stores.

    We keep our retail locations in Salesforce.com as contacts under a master account, which is shared with all users using a special account sharing rule.

    The solution I came up with was a simple flow that limited users to a specific set of enterable information, pre-filling the date of the activity, and marking the task complete when the activity was committed. Literally, the only thing they needed to do was select a picklist value and enter a comment about their visit. It was exactly what we were looking for.

    The thing I didn’t like about the flow was that when a user entered it, context kind of got lost – meaning they started out from a contact record, but didn’t have a good visual cue about where they were once they got into the flow.

    Sure, the flow was simple, but to me it’s still poor UX not to know the context of your work at all times. So, I decided to use a Visualforce page to solve the problem:

    <apex:page standardController="Contact">
        <apex:sectionheader title="Add Retail Store Visit" subtitle="{!Contact.Name}"></apex:sectionheader>
        <flow:interview name="Retail_Store_Visit">
            <apex:param name="vContact" value="{!Contact.Id}"></apex:param>
            <apex:param name="vAccount" value="{!Contact.Account.Id}"></apex:param>
        </flow:interview>
    </apex:page>
    

    The trouble with this was that after the flow data was committed, the user would be returned to the beginning of the flow. That’s definitely not what I wanted. I needed to go back to the contact record I started from.

    So I added the finishLocation attribute to the <flow:interview /> component tag. It would make sense that if I passed the Contact Id, the flow should return to the Contact record:

    <flow:interview name="Retail_Store_Visit" finishLocation="{!URLFOR('/' + Contact.Id)}">
        <apex:param name="vContact" value="{!Contact.Id}"></apex:param>
        <apex:param name="vAccount" value="{!Contact.Account.Id}"></apex:param>
    </flow:interview>
    

    Nope. That didn’t do it. When the flow is entered, context gets lost, so Salesforce doesn’t really know where the user is anymore. Even using the vContact Apex parameter didn’t work.

    I searched help documentation for an answer, but it wasn’t all that helpful. I searched Communities and came up empty. Then I searched the Salesforce Stack Exchange, where the only solution I could find was really convoluted, and didn’t even come close to solving my problem. I was vexed.

    Taking a break to get a cup of coffee, a solution dawned on me that turned out to be pretty darned simple. All I needed was an Apex variable in the page, which I could pass to the finishLocation component tag once the flow was complete. Oddly enough, this method is not documented – at least not that I could find.

    So…the final Visualforce page:

    <apex:page standardController="Contact">
        <apex:variable var="theContact" value="{!Contact.Id}"></apex:variable>
        <apex:sectionheader title="Add Retail Store Visit" subtitle="{!Contact.Name}"></apex:sectionheader>
        <flow:interview name="Retail_Store_Visit" finishLocation="{!URLFOR('/' & theContact)}">
            <apex:param name="vContact" value="{!Contact.Id}"></apex:param>
            <apex:param name="vAccount" value="{!Contact.Account.Id}"></apex:param>
        </flow:interview>
    </apex:page>
    

    Using the Apex variable, users where returned to the contact record they started from, and could see the task they just added in the activity history related list. This was exactly what I was looking for. Everyone was happy.

    If you need to return to a starting point when using flows and Visualforce pages, consider giving this solution a try.

  • Making a Field Appear Required on a Visualforce Page

    I’ve been working on a force.com app with the requirement that a user must enter a valid email address on a Visualforce page before being able to save a record.

    But they must also be able to insert the related contact’s email address by clicking a button instead of having to leave the edit page to go find it. That seemed simple enough, but it wasn’t. This is my solution for making a field appear required on a Visualforce page.

    In my original Visualforce page, it seemed logical that if I set the recipient email field as required, all would work as expected. However, defining the field as required prevented my custom action in my page controller from firing and entering the email address.

    Original Page Controller

    public class GiftCardTestController {
        private ApexPages.StandardController std;
        public String cEmail {get;set;}
        public Gift_Card_Order__c gc {get;set;}
        public GiftCardTestController(ApexPages.StandardController stdCtrl) {
            std = stdCtrl;
        }
    
        //selects the email address of the related contact
        //and inserts into recipient email field.
        public void fillEmail() {
            gc = (Gift_Card_Order__c)std.getRecord();
            cEmail = [select Id, Email from Contact where Id = :gc.Contact__c].Email;
            gc.Recipient_Email__c = cEmail;
        }
    }
    

    Original Visualforce Page

    <apex:page standardController="Gift_Card_Order__c" extensions="GiftCardTestController" title="Gift Card Test">
        <apex:form>
            <apex:pageblock title="Gift Card" mode="edit">
                <apex:pageblockbuttons location="top">
                    <apex:commandbutton action="{!save}" value="Save"></apex:commandbutton>
                    <apex:commandbutton action="{!cancel}" value="Cancel"></apex:commandbutton>
                    <apex:commandbutton action="{!fillEmail}" value="Fill Email"></apex:commandbutton>
                </apex:pageblockbuttons>
                <apex:pageblocksection title="Email Info" columns="1">
                    <apex:inputfield value="{!Gift_Card_Order__c.Contact__c}"></apex:inputfield>
                    <apex:inputfield value="{!Gift_Card_Order__c.Recipient_Email__c}" required="true"></apex:inputfield>
                </apex:pageblocksection>
            </apex:pageblock>
        </apex:form>
    </apex:page>
    

    In this example, the fillEmail() action should select the related contact email address, and put the value in the Recipient_Email__c field so the user can see it.

    But it’s not that simple it seems. When the field had the required=“true” attribute set, the action would not fire because all validation is done on the client side and the page never posts back to the server — so the controller action never gets called.

    So after some digging and asking for help on the Salesforce discussion boards, the solution was to make the Recipient_Email__c appear as if it’s required on the page (though it’s really not), and add a new save method to my controller to handle field validation on the server side when the record gets saved.

    New Page Controller

    public class GiftCardTestController {
        private ApexPages.StandardController std;
        public String cEmail {get;set;}
        public Gift_Card_Order__c gc {get;set;}
        public GiftCardTestController(ApexPages.StandardController stdCtrl) {
            std = stdCtrl;
        }
    
        public void fillEmail() {
            gc = (Gift_Card_Order__c)std.getRecord();
            cEmail = [select Id, Email from Contact where Id = :gc.Contact__c].Email;
            gc.Recipient_Email__c = cEmail;
        }
    
        // add custom save method...
        public pageReference save() {
            gc = (Gift_Card_Order__c)std.getRecord();
    
            // if the recipient email is null, add an error to the field
            // and return null to remain on the current page...
            if(gc.Recipient_Email__c == null) {
                gc.Recipient_Email__c.addError('A valid email address is required.');
                return null;
            }
    
            // otherwise, the field is filled, so it's okay to redirect to view page.
            // standard field validation will check for valid email format.
            else {
                return std.save();
            }
        }
    }
    

    New Visualforce Page

    <apex:page standardController="Gift_Card_Order__c" extensions="GiftCardTestController" title="Gift Card Test">
        <apex:form>
            <apex:pageblock title="Gift Card" mode="edit">
                <apex:pageblockbuttons location="top">
                    <apex:commandbutton action="{!save}" value="Save"></apex:commandbutton>
                    <apex:commandbutton action="{!cancel}" value="Cancel"></apex:commandbutton>
                    <apex:commandbutton action="{!fillEmail}" value="Fill Email"></apex:commandbutton>
                </apex:pageblockbuttons>
                <apex:pageblocksection title="Email Information" columns="1">
                    <apex:inputfield value="{!Gift_Card_Order__c.Contact__c}"></apex:inputfield>
    
                    <!-- Updated pageBlockSectionItem -->
                    <apex:pageblocksectionitem>
                        <apex:outputlabel>Email Recipient</apex:outputlabel>
                        <apex:outputpanel layout="block" styleClass="requiredInput">
                            <apex:outputpanel layout="block" styleClass="requiredBlock"></apex:outputpanel>
                            <apex:inputfield value="{!Gift_Card_Order__c.Recipient_Email__c}"></apex:inputfield>
                        </apex:outputpanel>
                    </apex:pageblocksectionitem>
                    <!--// end pageBlockSectionItem -->
    
                </apex:pageblocksection>
            </apex:pageblock>
        </apex:form>
    </apex:page>
    

    Notice the <apex:pageblocksectionitem /> code to replace the original field. This is how we make the field appear with the “required” bar. A nifty trick that took some digging to discover. Hopefully, this post saves someone else the time it took me to figure it out — and me the time when I forget it.

    For convenience, here’s a Github Gist with field label & inline help that shows exactly how to make a field appear required on a Visualforce page.

  • AppleScript to Add Files in the Mac Finder

    Today I had the need to add a bunch of named text files to a folder in the Finder on my Mac.

    I found it a major pain to open BBEdit, make a new document, save it to where I wanted it, and then manually copy & rename the file back in the Finder. A lot of effort just to get 7 or 8 empty files with different names.

    So, I threw together this little AppleScript to add empty files instead. The gist is once launched in the Finder (using FastScripts by Red Sweater naturally. Keystroke: cmd+option+shift+N), a dialog pops up that lets you enter a file title. Then the Finder creates that file in the front-most window. If no window is open, the file is added to your Desktop.

    I found this to be more than twice as fast as the “traditional” method of making several files. Hopefully, it can help you out too. Remember, use it with FastScripts for quick keystroke access. Save as a script in the “Finder” scripts folder (“~/Library/Scripts/Applications/Finder/”).

    Here’s the code. Download the source, open up and copy/paste into AppleScript Editor and save…

    property defaultFileName : "newFile.txt"
    tell me to activate
    set theFileName to text returned of (display dialog "Enter a file name:" default answer defaultFileName)
    tell application "Finder"
        activate
        if the (count of windows) is not 0 then
            set theFolder to (folder of the front window) as text
            set theFolder to POSIX path of theFolder
        else
            set theFolder to POSIX path of (get path to desktop)
        end if
        set addedFile to (theFolder & theFileName)
        do shell script "touch '" & addedFile & "'"
        if the (count of windows) is not 0 then
            set addedFile to (POSIX file addedFile) as alias
            select addedFile
        end if
    end tell
    
Older Posts →