Category: Uncategorized

  • Run Your Entire Web Dev Workflow From Your Phone (Claude Code + a Tunnel)

    Run Your Entire Web Dev Workflow From Your Phone (Claude Code + a Tunnel)

    There’s a specific kind of frustration that shows up the moment you start driving Claude Code from your phone.

    The coding part works beautifully. You’re on a bus, or in a queue, or lying on the couch, and you can read what Claude is doing, approve a tool call, tell it to refactor the header, ask it to fix the failing test. Your laptop is at your desk doing the work. Your phone is the steering wheel.

    Then Claude says “done – check it out at http://localhost:3000” and the whole thing falls apart. Your phone has no idea what localhost:3000 means. That address points at your phone, not your laptop. You are now a developer who can write code but cannot look at it.

    The fix is two pieces stacked on top of each other: Remote Control for driving the session, and a tunnel for seeing the result. Here’s how to wire both up.




    Part 1: Get Claude Code onto your phone

    Claude Code has a Remote Control feature that connects a session running on your machine to the Claude mobile app. The session never leaves your laptop – your files, your dev server, your node_modules all stay put. The phone is just a window into that terminal.

    Start it from your project folder:

    claude --remote-control "My App"
    
    Enter fullscreen mode

    Exit fullscreen mode

    You get a normal interactive session at your desk and the same session on your phone. If you’re already mid-conversation, /remote-control (or /rc) does the same thing without losing your history. If you’re walking away entirely, claude remote-control runs it in server mode with no local prompt.

    Either way, Claude Code prints a session URL and a QR code. Scan the QR into the Claude app, or open the app, tap Code, and pick the session from the list. That’s the whole setup.

    Two things worth doing while you’re at the desk:

    • Turn on push notifications. Run /config and enable pushes. Now your phone buzzes when a build finishes or Claude needs a decision, instead of you checking every few minutes. You can also ask inline: “notify me when the tests pass.”
    • Check you’re eligible. Remote Control needs a paid claude.ai plan and claude auth login – API keys won’t work. If it refuses to start, claude doctor says why.



    Part 2: Why you still can’t see your app

    You’ve got Claude in your pocket. You tell it to change the hero section. It does. And you’re stuck, because the dev server is bound to 127.0.0.1:5173 on a laptop that’s behind your router, behind your ISP’s NAT, with no public address.

    Being on the same Wi-Fi sometimes helps – you can occasionally reach http://192.168.1.x:5173 if your dev server binds to 0.0.0.0. But that dies the moment you leave the house, and it’s exactly when you leave the house that this whole setup becomes worth doing.

    What you actually want is a tunnel: a small daemon on your laptop that opens an outbound connection to a public edge server, which then forwards inbound requests back down that pipe to your local port. No firewall changes. No port forwarding. No public IP.




    Part 3: Picking a tunnel

    Three realistic options, and the free tiers diverge sharply.



    Cloudflare Tunnel – the best free option

    Two flavours, and the distinction matters more than most tutorials admit.

    Quick tunnel (no account, one command):

    cloudflared tunnel --url http://localhost:5173
    
    Enter fullscreen mode

    Exit fullscreen mode

    You get a random trycloudflare.com subdomain, printed to your terminal. Copy it to your phone and you’re browsing your local app from anywhere. Zero setup.

    The catch: quick tunnels are explicitly meant for development and testing. Expect a cap on in-flight requests, no Server-Sent Events support, no SLA, and a brand new URL every time you restart. For “look at my dev server for the next two hours,” that’s completely fine. For anything you want to leave running, it isn’t.

    Named tunnel (account + your domain on Cloudflare DNS):

    More setup – you create the tunnel, route DNS to it, and usually end up managing a config.yml or a system service. In exchange you get a stable URL on your own domain that survives restarts, free SSL, no bandwidth caps, no session timeouts, and you can put Cloudflare Access in front of it so only you can load the page. The requirement is that your domain’s authoritative DNS lives on Cloudflare.

    If you’re going to do this more than twice, spend the twenty minutes on a named tunnel. dev.yourdomain.com pointing at your laptop is a genuinely nice thing to own.



    ngrok – fastest to first URL, tightest free tier

    ngrok http 5173
    
    Enter fullscreen mode

    Exit fullscreen mode

    Still the quickest path from nothing to a public URL, and its request inspector is better than anything Cloudflare gives you – useful if you’re debugging webhooks rather than just eyeballing a page. Every account gets a free static domain, so your URL doesn’t rotate on restart.

    But ngrok cut its free plan hard in early 2026: roughly 2-hour session limits, about 1 GB of monthly bandwidth, a handful of endpoints, and an interstitial warning page in front of every visit. The two-hour ceiling is the one that hurts here – you’ll be restarting the tunnel and re-copying URLs in the middle of your afternoon. Removing the interstitial means paying.



    Expose – good if you’re already in PHP land

    expose share http://localhost:8000
    
    Enter fullscreen mode

    Exit fullscreen mode

    Beyond Code’s tool, self-hostable, and pleasant if you’re doing Laravel work. The shared free tier has session limits similar in spirit to ngrok’s. Its real selling point is that you can run your own Expose server on a cheap VPS and stop worrying about anyone’s free tier.



    Quick comparison

    Cloudflare quick Cloudflare named ngrok free Expose (shared)
    Account needed No Yes Yes Yes
    Setup time ~1 min ~20 min ~2 min ~2 min
    Session limit None None ~2 hours Limited
    Stable URL No Yes (your domain) Yes (static domain) No
    Bandwidth cap None stated None ~1 GB/mo Limited
    Interstitial page No No Yes No
    Best for A quick look Leaving it running Webhook debugging PHP/Laravel

    Recommendation: quick tunnel today because you want to get moving, named tunnel this weekend because you’ll want it permanently.




    Part 4: The dev-server config that will bite you

    This is the step nobody warns you about, and it produces a blank page or a scary error banner that looks like the tunnel is broken. It isn’t. Modern dev servers reject requests whose Host header doesn’t match localhost, as a defence against DNS rebinding attacks. Your tunnel’s hostname is, by definition, not localhost.

    Vite – add the tunnel host to vite.config.js:

    export default {
      server: {
        host: true,              // bind 0.0.0.0
        allowedHosts: ['.trycloudflare.com', 'dev.yourdomain.com'],
        hmr: { clientPort: 443 } // HMR over the tunnel's HTTPS
      }
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    That hmr.clientPort line is what makes hot reload keep working through the tunnel. Without it the page loads but never updates, and you’ll waste ten minutes wondering why Claude’s changes aren’t showing up.

    Next.js – add allowedDevOrigins in next.config.js:

    module.exports = {
      allowedDevOrigins: ['dev.yourdomain.com', '*.trycloudflare.com']
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    WordPress through Herd has the same shape of problem with a different cause: WordPress stores the site URL in the database, so the tunneled page loads as bare HTML while every asset still points at my-site.test.

    Herd installs Expose into your PATH and gives you a token field in settings, so from the site directory the tunnel is one command:

    herd share
    
    Enter fullscreen mode

    Exit fullscreen mode

    Herd detects the site’s local URL and shares the right address. Now teach WordPress to answer on the public hostname, in wp-config.php above the “stop editing” line:

    $tunnel_host = $_SERVER['HTTP_X_FORWARDED_HOST'] ?? '';
    
    if (str_contains($tunnel_host, 'sharedwithexpose.com')) {
        $_SERVER['HTTP_HOST'] = $tunnel_host;
        $_SERVER['HTTPS']     = 'on';
        define('WP_HOME',       'https://' . $tunnel_host);
        define('WP_SITEURL',    'https://' . $tunnel_host);
        define('COOKIE_DOMAIN', $tunnel_host);
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    Keep it conditional – hardcoding WP_SITEURL to the tunnel fixes the phone and breaks local .test access. Matching the suffix rather than an exact domain means it survives the free plan’s rotating subdomains. The HTTPS line stops WordPress emitting http:// URLs onto an https:// page, since Expose terminates TLS before PHP sees the request.

    Confirm the header name before trusting that snippet. Expose rewrites Host so Herd can pick the right site, which means the public hostname arrives in a forwarded header – load the tunnel on your phone, then read the actual request headers in Expose’s dashboard at http://127.0.0.1:4040 and swap the key if it differs.

    URLs baked into post content still point at .test, and multisite is worse again – don’t tunnel that one.

    While you’re here, tell Claude about it once and never think about it again. Drop this in your CLAUDE.md:

    ## Mobile preview
    This project is previewed through a Cloudflare tunnel at dev.yourdomain.com.
    When adding a dev server config, keep `allowedHosts` and HMR clientPort 443 intact.
    Never hardcode localhost URLs in client-side code - use relative paths.
    
    Enter fullscreen mode

    Exit fullscreen mode

    That last line matters more than it looks. A hardcoded http://localhost:8000/api in your frontend works perfectly on your laptop and fails silently on your phone, because your phone’s “localhost” is your phone.




    Part 5: Putting it together

    The full startup sequence, run once at your desk before you go anywhere:

    # Terminal 1 - your app
    npm run dev
    
    # Terminal 2 - the tunnel
    cloudflared tunnel --url http://localhost:5173
    
    # Terminal 3 - Claude, with Remote Control on
    cd ~/projects/my-app
    claude --remote-control "My App"
    
    Enter fullscreen mode

    Exit fullscreen mode

    Then: scan the QR code into the Claude app, copy the tunnel URL into your phone’s browser, and put both on your home screen or in split view. That’s the whole rig.

    The loop, once you’re out of the house:

    1. Type into the Claude app. “The mobile nav overlaps the logo below 400px. Fix it.”
    2. Claude works on your laptop. You watch the tool calls stream by. Approve anything it asks about.
    3. Switch to your browser tab, pull to refresh. Or don’t – with HMR configured, it’s usually already updated.
    4. Screenshot the problem and send it back. This is the part that feels like cheating. Attach a photo or screenshot in the Claude app; Claude sees the image directly as part of your message. “Still overlapping, see attached” is a complete bug report.
    5. Repeat.



    Part 6: The things that will go wrong

    Your laptop must stay awake. Both the session and the tunnel are local processes – a closed lid ends the party. Disable sleep on AC power. This is a preview mechanism, not hosting; if you want the app up permanently, deploy it.

    Your dev server is now public. A trycloudflare.com URL is unguessable but has no auth in front of it. Never tunnel a production database, an admin panel, or a debug endpoint, use fake data locally, and stop the tunnel when you’re done. On a named tunnel, put Cloudflare Access in front and the problem goes away.

    Dropped sessions come back. Ctrl+C’d out of claude remote-control? Run it again in the same directory within a few hours and it picks up where it left off.

    Set it up once. The next time you have an idea on a walk, you can just build it.

  • Beyond the Chat Box: Engineering Autonomous AI with the Claude Developer Platform

    Beyond the Chat Box: Engineering Autonomous AI with the Claude Developer Platform

    If you’re a developer, you’ve almost certainly used Claude. You might use it to debug a stubborn function, write a script, or brainstorm a project architecture. But there is a massive gulf between typing prompts into a browser window and building a production-ready, autonomous software system.

    I recently dove into Anthropic’s Claude Platform 101 course, and it is the ultimate blueprint for bridging that gap. It completely flips the script on how we interact with Large Language Models (LLMs)—shifting our perspective from making a single “request and response” to designing self-sustaining agent loops.

    Here is my complete breakdown of what the course covers, the core shifts in mental models you need to make, and how to start building product-ready AI.

    1. The Core Mental Model: The Three Layers of the Platform

    When building programmatically with Claude, you aren’t just “asking questions.” You are utilizing a three-tiered infrastructure designed to scale:

    • Primitives (Build): These are your core API building blocks—the Messages API, tool use definitions, prompt caching, and specialized features like web search, code execution, and Model Context Protocol (MCP) servers.
    • Infrastructure (Scale): The engine that keeps autonomous systems running smoothly. This layer handles managed agents, retries, queues, and context management.
    • Controls (Run): The enterprise-grade tools used to monitor performance, evaluate outputs (evals), manage workspaces, and strictly enforce usage and spend limits.

    The Shorthand: Build with primitives, scale on infrastructure, and run with absolute control.

    2. Anatomy of Your First Production Request

    A basic API call requires three foundational parameters passed to the messages.create method:

    1. Model: Defining your intelligence tier (e.g., claude-opus-4-8).
    2. Max Tokens: A mandatory safety cap limiting the response length.
    3. Messages: An array of structured communication objects specifying roles like user or assistant.

    Handling the “Array of Blocks”

    Unlike standard text completion APIs that return a single, raw string, Claude returns an array of content blocks (e.g., text blocks, tool calls, or thinking blocks). In production, your code must loop through this array and conditionally handle what Claude sends back based on the block type.

    3. Tiering Your Code: Choosing the Right Model

    Anthropic provides distinct model tiers, and the course stresses a vital production rule: The right model is the cheapest one whose output you would actually ship.

    To build cost-effectively, establish an evaluation (eval) using 20 to 30 representative real-world examples, and test them progressively:

    • Claude Haiku: Lightning-fast and low cost. Ideal for high-volume text classification and routing. Start here.
    • Claude Sonnet: The general-purpose production “sweet spot,” balancing high intelligence with speed.
    • Claude Opus & Fable: Powerhouse models optimized for deep reasoning, heavy mathematics, and multi-step coding. Use these strictly when lesser models fail the eval.

    4. Understanding and Mastering the “Agent Loop”

    The absolute heart of the course is mastering the Agent Loop. An agent is an autonomous script where Claude handles both sides of a messaging loop without a human operator in the middle.

    How the Mechanics Work

    The entire framework relies on watching the API’s stop_reason:

    • tool_use: Claude halts generation because it needs to interact with the real world. Your code intercepts the request, runs the actual function locally (e.g., querying your database), appends the result to the chat history, and sends it right back to Claude.
    • end_turn: Claude decides it has successfully gathered enough information, breaks the loop, and delivers the final answer.

    Skipping Boilerplate with the Tool Runner

    Writing these while loops and hand-crafting complex JSON schemas for your native functions can lead to thousands of lines of redundant code. The Claude SDK addresses this with the Tool Runner:

    const runner = client.beta.messages.toolRunner({
    model: "claude-sonnet-4-6",
    max_tokens: 1024,
    messages: [{ role: "user", content: "What's the status of server 4?" }],
    tools: [getServerStatus, rebootServer], // Direct native programming functions
    });
    
    const finalMessage = await runner.untilDone();

    The runner reads your native code’s types/documentation to generate the schemas automatically, and untilDone() manages the ping-pong cycle of execution behind the scenes.

    4. Tools vs. Skills vs. MCP

    As your agentic systems grow, organizing how Claude interacts with instructions and code can get messy. The course provides an elegant framework to keep them separated:

    ComponentWhat it representsIdeal Use Case
    ToolsWhat Claude can do internally.Connecting Claude to your proprietary databases or internal APIs.
    SkillsHow you want a process done.Standardizing templates, output rules, or compliance checklists (SKILL.md).
    MCPConnecting to everyone else’s stuff.Zero-maintenance integrations with third-party apps like Slack, Jira, or Google Calendar.

    6. Context Management: Keeping it Affordable

    stuffing thousands of historical conversation tokens into every single request will quickly break your API budget. The course outlines a layered approach to context management:

    • Just-in-Time Context: Keep the initial prompt lean. Give Claude a lookup tool to fetch large documents only when it explicitly needs them.
    • Server-Side Compaction: Use {"type": "compact"} to let the API automatically summarize old chat history once it crosses a size threshold.
    • Prompt Caching: Cache massive system instructions or data files on Anthropic’s servers to reuse them across repeated calls at a fraction of the cost and latency.

    7. The Ultimate Horizon: Managed Agents

    If you don’t want to manage sandboxes, security containers, or loop states on your own local servers, you can hand everything over to Claude Managed Agents.

    Managed agents execute tasks completely on Anthropic’s hosted infrastructure inside isolated, secure cloud containers equipped with full file-system access, web search capabilities, and customizable environments. You simply pass a behavioral rubric, and a secondary grader LLM will force the agent to iteratively fix its mistakes in the sandbox until your target criteria are fully met.

    Final Thoughts

    Transitioning from a casual AI user to an AI systems engineer requires dropping the chatbot mentality. The Claude Platform 101 course makes it clear that the future of software development isn’t about writing massive, static prompt strings—it’s about building tight, dynamic, tool-enabled loops that allow Claude to reason, act, and self-correct safely.

    Are you building with the Claude API? What patterns are you using to manage your agent loops? Let me know in the comments below!

  • Manage WooCommerce Store Completely From the Frontend

    Manage WooCommerce Store Completely From the Frontend

    Have you ever wished you could run your own/client WooCommerce store without ever logging into the WordPress admin?

    If you’ve handed your store over to a shop manager — or you’re the owner who just wants to add a product and check today’s sales without wading through menus, plugins, and settings you don’t need — the standard WooCommerce admin can feel like a lot. Too many screens. Too much clutter. Too many places a non-technical team member can accidentally break something.

    That’s exactly the problem StoreSuite sets out to solve. It gives you a clean, modern frontend dashboard where you (and your team) can manage everything — products, orders, coupons, categories, and analytics — from one place. No wp-admin. No clutter. Just your store.

    And here’s the part most people don’t expect: StoreSuite ships features for free that other store-management dashboards usually lock behind a Pro plan — including AI content and image generation, full variable product support, real-time analytics, and CSV export. Let’s walk through it.



    What is StoreSuite?

    StoreSuite is a WordPress plugin that adds a frontend store-management dashboard to your WooCommerce shop. Instead of giving your team access to the WordPress backend, you give them a single page on your own site where they can do everything day-to-day:

    • Add and edit products (every type — simple, variable, grouped, external)
    • View, create, and edit orders
    • Build and manage coupons
    • Organize categories, tags, brands, and attributes
    • Watch real-time sales numbers and leaderboards
    • Generate product titles, descriptions, and images with AI

    It requires WooCommerce, it’s fully compatible with WooCommerce HPOS (High-Performance Order Storage), and access is gated by the manage_woocommerce capability — so only administrators and shop managers get in.

    StoreSuite frontend dashboard



    Why Manage Your Store From the Frontend?

    A quick honest list of why this matters:

    • Less risk. Your shop manager/owner never sees plugin settings, theme files, or anything they could break. They see your store — nothing else.
    • Less clutter. No third-party plugin notices, no unrelated admin menus. StoreSuite even strips out theme and conflicting plugin styles on its own pages so the dashboard stays clean and fast.
    • Faster work. Everything is one or two clicks away. Add a product, check an order, spin up a coupon — without hunting through the backend.

    Now let’s look at what you can actually do.



    1. A Dashboard That Shows Your Store at a Glance

    Log in, land on the dashboard, and within a few seconds you know how your store is doing. That’s the whole idea.

    The dashboard home greets you with your store’s pulse — a row of performance boxes showing the numbers that matter: net sales, orders, average order value, returns, discounts, and products sold. Each box carries a small percentage badge so you can see how today compares to yesterday (or this month vs. last month, or this December vs. last December — your choice).

    Below that sits a net-sales chart you can switch between line and bar views and group by day, week, or month. Then come the leaderboards — top products, top categories, top customers, top coupons — and a Recent Orders table so you can spot anything that needs attention.

    Finally, a Quick Actions grid gives you one-click shortcuts to the things you do most: add a product, view orders, create a coupon, and more.



    2. Complete Product Management

    This is where most store owners spend their time, and StoreSuite makes it effortless.

    Products list in StoreSuite

    The Products list is your home base. Every product appears in a clean table with its image, name, category, status, SKU, a color-coded stock badge, price (with the old price crossed out on sale items), and type. From here you can:

    • Search any product by name instantly
    • Filter by category, product type, stock status, or brand — and combine them (for example, out-of-stock products in the Clothing category)
    • Quick edit the basics (name, price, stock, status) right from the list
    • Use bulk actions to edit, trash, or export many products at once



    Add or edit any product type

    StoreSuite handles every WooCommerce product type — simple, variable, grouped, and external/affiliate. The add/edit form walks you through everything top to bottom, but only the title is truly required, so you can start simple and polish later.

    You get full control over pricing (including scheduled sales that turn themselves on and off), inventory with low-stock thresholds and backorders, shipping, upsells and cross-sells, catalog visibility, and more.

    Editing a variable product

    Variable products get special love: manage attributes and variations, run bulk actions, and use generate-all-variations to create every size/color combination in one click — something many “free” dashboards simply don’t offer.



    3. AI That Writes and Designs For You

    Here’s StoreSuite’s standout feature — and it’s completely free.

    Writing product descriptions is the part most store owners dread. StoreSuite hands it to AI:

    • Per-field generation — a “Generate with AI” button on the product title, short description, and long description. Each one opens an editable suggestion you can tweak, regenerate, or step through previous suggestions with a history pager.
    • All-in-one generator — type a single hint and StoreSuite drafts the title, short description, and long description together.
    • AI image generation — describe a featured or gallery image, preview it, regenerate, and drop it straight into your media library.

    AI settings page

    You stay in control with a dedicated AI settings page, where you can turn generation on or off per field and set your own custom instructions for each text field and for images.

    StoreSuite uses a “bring your own AI” approach — it’s built on the WordPress 7.0 core AI connector, so generation runs on the provider and keys you configure. (If your site is on an older WordPress version, the AI features simply hide themselves.)



    4. Full Order Management

    Orders list in StoreSuite

    Orders are front and center. From the Orders section you can:

    • View every order with its number, customer, date, total, and a color-coded status badge
    • Open any order to see full customer and line-item details
    • Create a new order by hand — perfect for phone or in-person sales
    • Edit existing orders when something needs changing

    Because StoreSuite is HPOS-compatible, it works smoothly even on high-volume stores using WooCommerce’s modern order storage.



    5. Coupons, Categories, Tags, Brands & Attributes

    Everything that keeps your catalog organized is here too.

    Coupons in StoreSuite

    • Coupons — create, edit, and manage WooCommerce discount codes with all the usual rules.
    • Categories, Tags, and Brands — add, edit, and list them without leaving the dashboard. The lists even refresh instantly if changes are made elsewhere (admin, REST API, an import).
    • Product Attributes — manage attributes and their terms, ready to power your variable products.

    To keep the sidebar tidy, Categories, Brands, and Tags are neatly nested under the Products menu.



    6. Export Your Products to CSV

    Need your catalog for reporting, accounting, or migrating to another store? StoreSuite includes CSV product export with a configurable export modal — select what you need and download it. Again, free, no upsell.



    7. Make It Your Own

    StoreSuite admin settings

    From WooCommerce → StoreSuite in your WordPress admin, you can shape the dashboard to fit your brand and workflow:

    • Branding — add a sidebar logo (expanded) and a sidebar icon (collapsed) from the media library.
    • Color palettes — choose a predefined palette or build a custom one with live preview.
    • Dashboard widgets — switch performance boxes and leaderboards on or off; show eight meaningful numbers instead of fifteen noisy ones.
    • Pagination — control how many items show per page on each list.

    There’s also a collapsible sidebar that toggles between a full menu and a slim icon-only rail, with your preference remembered in the browser.



    How to Get Started

    Setting up StoreSuite takes about two minutes:

    1. Install and activate WooCommerce (if you haven’t already).
    2. Install and activate StoreSuite from Plugins → Add New (search “StoreSuite”).
    3. On activation, StoreSuite automatically creates a dashboard page with the You have no permission to view this page shortcode and selects it for you. If it didn’t, create a page, add the shortcode, and publish.
    4. Go to WooCommerce → StoreSuite → General and confirm your dashboard page is selected, then Save Changes.
    5. Visit that page while logged in with store-management permissions — and you’re managing your store from the frontend.

    If a dashboard URL ever returns a 404, just go to Settings → Permalinks and click Save Changes to refresh the routes.



    Final Thoughts

    Running a WooCommerce store shouldn’t mean living inside the WordPress admin. StoreSuite gives you and your team a clean, fast, frontend home for everything that matters — products, orders, coupons, your whole catalog, and real-time analytics — plus AI that writes your descriptions and creates your images.

    And it does all of it with no feature gates, no trial limits, and no upsell. The premium-grade tools other dashboards charge for are simply included.

    If you’ve been looking for the easiest way to manage your WooCommerce shop completely from the frontend, give StoreSuite a try — your morning store check-in is about to get a whole lot shorter.

    Get StoreSuite free from the WordPress plugin directory →

  • How to Set Up an Existing WordPress VIP Site Locally on macOS

    How to Set Up an Existing WordPress VIP Site Locally on macOS

    A quick guide to cloning a live WordPress VIP site to your MacBook for local development. Follow these commands in order.

    Step 1: Install the Required Tools

    Install Docker Desktop and VIP-CLI:

    brew install --cask docker
    npm install -g @automattic/vip
    

    After installing Docker, open it from your Applications folder so it starts running in the background.

    Verify all tools are installed:

    vip -v && node -v && npm -v && docker --version

    Please skip Step 2 & Step 3 if you are setting up an existing WordPress VIP site from a backup instead of cloning the WPVIP GitHub repository.

    Step 2: Log In to VIP-CLI

    vip logout   # in case of stale session
    vip login
    

    The logout command clears any old session. vip login opens a browser window to authenticate with your VIP account.

    Step 3: Clone the Site Repository

    cd ~/Sites
    git clone git@github.com:wpcomvip/your-site-name.git
    cd your-site-name
    

    Replace your-site-name with the actual repository name from your VIP application.

    Step 4: Create the Local Environment

    vip dev-env create --slug=your-site
    

    You can name –slug anything unique you want but follow the rules lowercase letters, numbers, and hyphens only. No spaces, no underscores, no special characters. Common conventions: wp-vip-test-site.

    A setup wizard will appear. Match production for PHP version, WordPress version, and multisite settings. When asked for the application code source, choose Local folder and provide the path to your cloned repo.

    • Site title: anything
    • Multisite: match production
    • PHP version: match production
    • WordPress version: match production
    • Source for application code: choose Local folder and give it the absolute path to your cloned repo (e.g. /Users/you/Sites/your-site-name)
    • Source for mu-plugins: auto (pulls VIP’s mu-plugins automatically)
    • Source for VIP MU plugins: auto

    Step 5: Start the Environment

    vip dev-env start --slug=your-site
    

    Once started, you’ll see the local site URL, login credentials, and an auto-login link. Save these for later.

    Step 6: Import the Database

    vip dev-env import sql /path/to/file.sql --slug=your-site
    

    Replace /path/to/file.sql with the actual path to your SQL dump on your Mac.

    Step 7: Import Media Files

    vip dev-env import media /path/to/wp-content/uploads --slug=your-site
    

    Replace /path/to/wp-content/uploads with the path to the uploads folder on your Mac. The folder should contain year-numbered subfolders (2023/, 2024/, etc.).

    Done

    Your local copy of the VIP site is now running. Open the site URL shown after vip dev-env start and log in with the credentials provided.

    Day-to-Day Useful Commands

    Once your environment is set up, these are the commands you’ll use most often.

    # List all your local environments
    vip dev-env list
    
    # Check status, URLs, and credentials
    vip dev-env info --slug=your-site
    
    # Start the environment
    vip dev-env start --slug=your-site
    
    # Stop the environment (frees up RAM and CPU)
    vip dev-env stop --slug=your-site
    
    # Run any WP-CLI command inside the container
    vip dev-env exec --slug=your-site -- wp plugin list
    vip dev-env exec --slug=your-site -- wp cache flush
    vip dev-env exec --slug=your-site -- wp user list
    
    # Create a new admin user
    vip dev-env exec --slug=your-site -- wp user create yourname you@example.com --role=administrator
    
    # Check site URL after import
    vip dev-env exec --slug=your-site -- wp option get siteurl
    vip dev-env exec --slug=your-site -- wp option get home
    
    # Search and replace URLs in the database
    vip dev-env exec --slug=your-site -- wp search-replace 'old-url' 'new-url' --skip-columns=guid
    
    # Delete all manually imported media files (host path - faster)
    rm -rf ~/.local/share/vip/dev-environment/your-site/uploads/*
    
    # Delete all manually imported media files (container path - alternative)
    vip dev-env exec --slug=your-site -- rm -rf /wp/wp-content/uploads/*
    
    # Destroy the environment completely
    vip dev-env destroy --slug=your-site
    
    # Update tooling to the latest version
    npm update -g @automattic/vip
    

    For official documentation, visit docs.wpvip.com/vip-local-development-environment.

  • How WordPress is Preparing for the AI Era

    How WordPress is Preparing for the AI Era

    We know WordPress is powerful, because of its thousands of plugins, APIs & functions but they are scattered. As a human we understand this ecosystem because we read docs to know how they works, features etc. But AI doesn’t work on this way. Because its not possible to know all the available WordPress plugins working procedure top to bottom. So the WordPress core AI team is taking a much smarter approach to use AI within the WordPress project. This approach is called AI Building Blocks for WordPress. The goal of the AI Building Blocks is Simple: Give AI a clear, secure, and standardized way to understand what WordPress can do and to do it safely.

    They are working on the three core technologies that work together:

    • PHP AI Client SDK & WordPress AI Client
    • Abilities API
    • MCP Adapter



    PHP AI Client SDK:

    Currently there are many AI providers (OpenAI, Anthropic, Gemini, etc.) in the market and each has its own API & configurations process. If a developer want to enable AI features to their own plugins they need to implement the API integration from scratch. Also the developers need to implement each providers separately for their plugins. Developers rebuilds the same infrastructure: provider integrations, API key management. Admin enter the same credentials multiple time and multiple places for each separate plugins.

    On the other hand, the PHP AI Client SDK creates one unified PHP interface that works with multiple AI models. To use the SDK everything will be centralizes, one credentials system for all plugins. The WordPress site admins choose which AI services they want to configure & use from a single place. So, developers can focus on building AI features, not AI infrastructure. Developers don’t lock themselves into a single AI provider.



    WordPress AI Client:

    An AI client and API for WordPress to communicate with any generative AI models of various capabilities using a uniform API. Built on top of the PHP AI Client, adapted for the WordPress ecosystem while following WordPress Coding Standards and best practices. Features of the WordPress AI Client:

    • WP Prompt Builder – A WordPress-friendly way to create and manage AI prompts using PHP, following WordPress coding standards.
    • Admin Settings Page – A WordPress Admin settings screen to store AI provider API keys.
    • Auto API Key Setup – Automatically uses API keys saved in WordPress settings.
    • Standard HTTP Client – Uses the WordPress HTTP API in a PSR-compatible way.
    • JavaScript API – Front-end JS prompt builder that talks with the server through the WP REST APIs.



    Abilities API:

    A typical WordPress website might could have lots of plugins installed & activated, each introducing unique functionality. But there’s no standardized way for these components to express their capabilities. An AI assistant has no systematic way to discover that. To solve this problem, the Abilities API establishes a standardized format for registering the capabilities of plugins and themes in a common structure, something like below:

    • What the plugin or feature does.
    • What inputs it needs.
    • What output it returns.
    • Which permission require to run it.

    This makes it easier for AI to automatically discover WordPress features. It transforms WordPress from an isolated collection of functionalities and plugins into an interconnected, discoverable system.



    MCP Adapter:

    Once WordPress knows its own abilities by Abilities API, the next step is letting AI assistants use them. That’s the job of the MCP Adapter.
    MCP (Model Context Protocol) is an open standard that defines how applications expose tools to AI models. The MCP Adapter translates WordPress abilities into a format that AI assistants like ChatGPT, Claude or Gemini can understand. AI assistants can discover, understand, and execute actions like creating posts, managing media, and moderating comments, all through the standardized protocol. So, Content creators can manage their WordPress sites conversationally, while developers can automate complex workflows across systems. Agencies can build sophisticated integrations, from content migration to performance optimization.



    These three AI Building Blocks work together by the following way:

    • PHP/WordPress AI Client SDK talks to AI models.
    • Abilities API defines what WordPress can do.
    • MCP Adapter exposes those abilities to AI assistants safely.



    AI Experiments

    If you want to experiments all the AI Building Blocks in one place then you can try AI Experiments Plugin. It serves as both a powerful tool for users and a reference implementation for developers, demonstrating how the PHP AI Client SDK, Abilities API, and MCP Adapter work together in practice.


    Human Written Content Certified

  • How to Migrate Your Local WordPress Site to a Vito Web Panel Server

    How to Migrate Your Local WordPress Site to a Vito Web Panel Server

    Follow this step-by-step guide to migrate your local WordPress website to a live server using the Vito Web Panel.




    1. Add Your SSH Key to the Vito Server

    First, generate an SSH key on your device and add it to the SSH Settings section inside the Vito server panel.



    2. Create a WordPress Site in Vito

    Create a new WordPress site from the Vito Web Panel.
    For example, assume your live domain is:

    wp-site.com
    
    Enter fullscreen mode

    Exit fullscreen mode



    3. Connect to the Vito Server via SSH

    Open your terminal and log in to your server using the following command:

    ssh vito@{your.server.ip}
    
    Enter fullscreen mode

    Exit fullscreen mode

    Once logged in, you will be at the server’s root directory.
    To list your created websites, run:

    ls or ls -la
    
    Enter fullscreen mode

    Exit fullscreen mode



    4. Navigate to Your Website Directory

    Enter your WordPress site directory:

    cd wp-site.com
    
    Enter fullscreen mode

    Exit fullscreen mode



    5. Remove the Existing wp-content Folder

    Delete the default wp-content directory:

    rm -rf wp-content
    
    Enter fullscreen mode

    Exit fullscreen mode



    6. Prepare Your Local wp-content for Upload

    Create a ZIP file of your local site’s wp-content folder.

    Before uploading, open the folder in a code editor and perform a search & replace:

    • Replace all instances of: local-wp-site.test with wp-site.com

    • Then replace: http://wp-site.com with https://wp-site.com



    7. Upload the wp-content ZIP to the Server

    Use SCP to upload the zipped folder to your server:

    scp ~/Herd/local-wp-site/wp-content.zip vito@ {your.server.ip}:/home/vito/wp-site.com/
    
    Enter fullscreen mode

    Exit fullscreen mode



    8. Unzip the Uploaded File

    From your project root directory, unzip the file:

    unzip wp-content.zip
    
    Enter fullscreen mode

    Exit fullscreen mode

    Now your site files are ready.



    9. Export Your Local Database

    Run the following command to export your local database:

    mysqldump -u root -p local_site_db > local_site_db.sql
    
    Enter fullscreen mode

    Exit fullscreen mode



    10. Upload the Database to the Server

    Upload the exported SQL file:

    scp ~/Herd/local-wp-site/local_site_db.sql vito@ {your.server.ip}:/home/vito/
    
    Enter fullscreen mode

    Exit fullscreen mode



    11. Import the Database Into the Live Server

    Run the following command to import your SQL file into the live database:

    mysql -u db_user_name -p wp_site_db < /home/vito/local_site_db.sql
    
    Enter fullscreen mode

    Exit fullscreen mode

    You will be prompted for the database password. Enter it, and the import will proceed.



    12. Update URLs Using WP-CLI

    Navigate back to your project’s root directory and run the following WP-CLI commands:

    wp search-replace 'local-wp-site.test' 'wp-test.com'
    
    Enter fullscreen mode

    Exit fullscreen mode

    wp search-replace 'http://wp-test.com' 'https://wp-test.com'
    
    Enter fullscreen mode

    Exit fullscreen mode

    This ensures all old local URLs are correctly replaced with the live domain URLs.


    Your migration is now complete!

  • A Beginner’s Guide to Global State Management in WordPress Gutenberg

    A Beginner’s Guide to Global State Management in WordPress Gutenberg

    When building complex WordPress block editor (Gutenberg) applications, managing state efficiently becomes crucial. This is where @wordpress/data comes into play. It allows you to manage and share global state across different blocks and components in your WordPress application.

    If you’re new to managing global state or using @wordpress/data, don’t worry! This blog post will walk you through the basics of reducers, actions, and selectors, explaining how to use them to manage state in WordPress.

    @wordpress/data provides a way to store, update, and access data globally, allowing different components or blocks to share and interact with the same data.



    Key Concepts in @wordpress/data

    To understand how to use @wordpress/data, we need to understand three main concepts: reducers, actions, and selectors. These form the core of how state is managed and updated.



    Actions:

    An action is like an instruction or command that tells the reducer what to do. It’s simply an object that has two parts:

    1. A type that indicates what kind of change is happening (e.g., add, remove, update).
    2. A payload that contains the data needed for that change (e.g., which item to add).

    Here’s an example of how actions might look in our cart example:

    const actions = {
        addToCart(item) {
            return {
                type: 'ADD_TO_CART', // Action type
                item // Payload: the item to add to the cart
            };
        },
        removeFromCart(itemId) {
            return {
                type: 'REMOVE_FROM_CART', // Action type
                itemId // Payload: the ID of the item to remove
            };
        }
    };
    
    Enter fullscreen mode

    Exit fullscreen mode

    In short: Actions tell the reducer what needs to change in the state.



    Reducers:

    A reducer is like a manager of your state. Whenever something changes in your application (e.g., a user adds a block or disables a feature), the reducer listens for that change and updates the state accordingly.

    What does a reducer do? It takes the current state and an action, then returns a new state based on the action.
    Here’s an example of a simple reducer that manages a shopping cart:

    const reducer = (state = { cart: [] }, action) => {
        switch (action.type) {
            case 'ADD_TO_CART':
                return {
                    ...state, // Keep the existing state
                    cart: [...state.cart, action.item] // Add the new item to the cart
                };
            case 'REMOVE_FROM_CART':
                return {
                    ...state,
                    cart: state.cart.filter((item) => item.id !== action.itemId) // Remove the item from the cart
                };
            default:
                return state; // Return the unchanged state for unknown actions
        }
    };
    
    Enter fullscreen mode

    Exit fullscreen mode

    In short: The reducer defines how the state changes when specific actions are dispatched.



    Selectors:

    A selector is a function that retrieves or selects specific data from the state. When your components need to access data (like displaying the items in the cart), they use a selector to fetch that data from the store.

    For example, a selector to get all the cart items might look like this:

    const selectors = {
        getCartItems(state) {
            return state.cart; // Return the cart items from the state
        }
    };
    
    Enter fullscreen mode

    Exit fullscreen mode

    In a component, you would use this selector to access the cart data like this:

    const cartItems = useSelect((select) => select('my-store').getCartItems());
    
    Enter fullscreen mode

    Exit fullscreen mode

    In short: A selector is a helper function that lets you access specific data from the state.



    Step by Step Guide to Implement Global State in Gutenberg with @wordpress/data

    Now that we’ve covered the basics, let’s walk through how you can implement these concepts in a Gutenberg block or component. We’ll set up a simple store with @wordpress/data, manage some state, and use actions and selectors to interact with that state.

    Step 1: Define Your Initial State
    First, we need to define the initial state of our store. This is the default data that our application starts with:

    const DEFAULT_STATE = {
        cart: []
    };
    
    Enter fullscreen mode

    Exit fullscreen mode

    Step 2: Create Actions
    Next, we define the actions that we will use to update the state. In our case, we’ll define two actions: one to add an item to the cart and another to remove an item.

    const actions = {
        addToCart(item) {
            return {
                type: 'ADD_TO_CART',
                item
            };
        },
        removeFromCart(itemId) {
            return {
                type: 'REMOVE_FROM_CART',
                itemId
            };
        }
    };
    
    Enter fullscreen mode

    Exit fullscreen mode

    Step 3: Create the Reducer
    The reducer listens for dispatched actions and updates the state accordingly. Here’s our reducer, which updates the cart when actions are dispatched:

    const reducer = (state = DEFAULT_STATE, action) => {
        switch (action.type) {
            case 'ADD_TO_CART':
                return {
                    ...state,
                    cart: [...state.cart, action.item]
                };
            case 'REMOVE_FROM_CART':
                return {
                    ...state,
                    cart: state.cart.filter((item) => item.id !== action.itemId)
                };
            default:
                return state;
        }
    };
    
    Enter fullscreen mode

    Exit fullscreen mode

    Step 4: Create Selectors
    Selectors help retrieve specific data from the state. For example, if we want to get all items in the cart, we would create a selector like this:

    const selectors = {
        getCartItems(state) {
            return state.cart;
        }
    };
    
    Enter fullscreen mode

    Exit fullscreen mode

    Step 5: Create and Register the Store
    Finally, we’ll create and register the store with the @wordpress/data package. This will make the store globally accessible across your WordPress site.

    import { createReduxStore, register } from '@wordpress/data';
    
    const store = createReduxStore('my-cart-store', {
        reducer,
        actions,
        selectors,
    });
    
    register(store);
    
    Enter fullscreen mode

    Exit fullscreen mode

    Step 6: Using the Store in Components
    Once the store is registered, you can use it in your Gutenberg blocks or components. For example, to add an item to the cart:

    import { useDispatch } from '@wordpress/data';
    
    const { addToCart } = useDispatch('my-cart-store');
    addToCart({ id: 1, name: 'Sample Item' });
    
    Enter fullscreen mode

    Exit fullscreen mode

    To fetch the items in the cart:

    import { useSelect } from '@wordpress/data';
    
    const cartItems = useSelect((select) => select('my-cart-store').getCartItems());
    
    Enter fullscreen mode

    Exit fullscreen mode



    Conclusion

    By understanding the roles of reducers, actions, and selectors, you can easily manage global state in your WordPress Gutenberg projects using @wordpress/data. This structured approach allows you to manage data more efficiently, making your blocks and components more powerful and interactive.

    With @wordpress/data, you have a reliable and scalable solution for handling state across your entire WordPress application. Give it a try in your next Gutenberg project!

  • How to Implement a WooCommerce AJAX Direct “Buy Now” Button

    How to Implement a WooCommerce AJAX Direct “Buy Now” Button

    When you’re running an online store using WooCommerce, making the purchasing process as seamless as possible is crucial. One effective way to do this is by adding a “Buy Now” button that allows customers to directly purchase a product without navigating through multiple pages. This blog will walk you through creating a WooCommerce AJAX “Buy Now” button using the provided code snippets.



    Step 1: Add the “Buy Now” Button

    First, you need to add a custom “Buy Now” button on your WooCommerce product pages. We’ll do this by hooking into the woocommerce_after_add_to_cart_button action, which places our button right after the standard “Add to Cart” button.

    Here’s the PHP code snippet:

    add_action( 'woocommerce_after_add_to_cart_button', 'add_content_after_addtocart' );
    function add_content_after_addtocart() {
        $current_product_id = get_the_ID();
        $product = wc_get_product( $current_product_id );
    
        if( $product->is_type( 'simple' ) ){
            echo '<button data-id="'.$current_product_id.'" class="buy-now button"><i class="matico-icon-toys"></i>'.__('Buy Now', 'woocommerce').'</button>';
        }
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    Explanation:

    • We use the woocommerce_after_add_to_cart_button hook to insert our “Buy Now” button right after the “Add to Cart” button.
    • The get_the_ID() function retrieves the current product ID, and wc_get_product() gets the product details.
    • We check if the product is of type simple and then render the button with the appropriate data-id attribute and a custom icon.



    Step 3: Enqueue the Script

    Next, you need to enqueue the script in your theme to ensure it’s loaded properly on your WooCommerce pages. Here’s how to do it:

    wp_enqueue_script('matico-child-script', get_stylesheet_directory_uri() . '/assets/js/script.js', array( 'jquery', 'scrollfix-script' ),  $matico_version, true);
    
    wp_localize_script( 'matico-child-script', 'matico_child_script_obj',
        array( 
            'checkout_page_url' => wc_get_checkout_url(),
        )
    );
    
    Enter fullscreen mode

    Exit fullscreen mode

    Explanation:

    • wp_enqueue_script() is used to load our custom script file (script.js), which contains the jQuery code.
    • wp_localize_script() passes PHP data to the script, such as the checkout page URL, allowing us to use it within the script.



    Step 2: Handle the AJAX Request

    Finally, we’ll handle the button click event using jQuery. The jQuery script sends an AJAX request to WooCommerce, which adds the product to the cart and then redirects the user directly to the checkout page.

    Here’s the jQuery code snippet:

    (function ($) {
        var MaticoChildThemeConfig = {
            init: function () {
                this.bindEvents();
            },
            bindEvents: function () {
                $(document).on('click', '.buy-now', this.handleBuyNowClick);
            },
            handleBuyNowClick: function (event) {
                event.preventDefault();
    
                var $button = $(this),
                    quantity = parseFloat($button.closest('.quantity').find('.qty').val()) || 1,
                    productID = $button.data('id');
    
                var data = {
                    product_id: productID,
                    quantity: quantity,
                };
    
                $.ajax({
                    type: 'POST',
                    url: wc_add_to_cart_params.wc_ajax_url.toString().replace('%%endpoint%%', 'add_to_cart'),
                    data: data,
                    dataType: 'json',
                    beforeSend: function () {
                        $button.addClass('loading');
                    },
                    success: function (res) {
                        if (res.error && res.product_url) {
                            window.location.href = res.product_url;
                        } else {
                            window.location.href = matico_child_script_obj.checkout_page_url;
                        }
                    }
                });
            }
        };
    
        MaticoChildThemeConfig.init();
    })(jQuery);
    
    Enter fullscreen mode

    Exit fullscreen mode

    Explanation:

    • When the “Buy Now” button is clicked, we prevent the default action to avoid page reload.
    • We gather the product ID and quantity from the current product page.
    • An AJAX request is sent to WooCommerce’s add_to_cart endpoint, which adds the product to the cart.
    • If the product is successfully added, we redirect the user to the checkout page. If there’s an error (e.g., the product is no longer available), the user is redirected to the product page.



    Conclusion

    By implementing the above steps, you can create a “Buy Now” button that streamlines the purchasing process for your customers. This feature is particularly useful in boosting conversions by reducing the number of clicks and pages a customer needs to navigate before completing a purchase.

  • মাতৃভাষা বাংলায় সিএসএস ফ্লেক্সবক্স

    মাতৃভাষা বাংলায় সিএসএস ফ্লেক্সবক্স

    আপনি যদি সিএসএস এ নতুন হন এবং যদি পিওর সিএসএস ব্যবহার করে সুন্দর সুন্দর ফ্লেক্সিবল লেআউট তৈরি করতে চান তাহলে সিএসএস ফ্লেক্সবক্স সম্পর্কে পরিষ্কার ধারনা রাখাটা আপনার জন্য খুবই জরুরী। এমনকি জনপ্রিয় সিএসএস ফ্রেমওয়ার্ক গুলো যেমনঃ Bootstrap লেআউট গ্রিড সিস্টেম ফ্লেক্সবক্স এর মাধ্যমে হ্যান্ডেল করে এছাড়াও আপনি যদি Tailwind সিএসএস নিয়েও কাজ করতে চান তাহলেও ফ্লেক্সবক্স জানা থাকাটা জরুরী। আমি এই আর্টিকেলটিতে চেষ্টা করব সিএসএস ৩.০ এর এই গুরুত্বপূর্ণ ডিসপ্লে প্রপার্টি ফ্লেক্সবক্স সম্পর্কে খুব সহজে পূর্ণাঙ্গ ধারনা দেয়ার। তাহলে চলুন শুরু করা যাক।



    সংক্ষেপে ফ্লেক্সবক্সঃ

    সিএসএস ফ্লেক্সবক্স হল একটি ফ্লেক্সিবল ডিসপ্লে প্রপার্টি। ফ্লেক্সবক্স এর সাহায্যে আমরা খুব সহজে একটি কন্টেইনার এর মধ্যে থাকা আইটেম গুলোকে x-axis অথবা y-axis বরাবর layout, space এবং alignment ঠিক করতে পারি।

    যে এলেমেন্ট এর ওপর display:flex প্রপার্টি অ্যাপ্লাই করা হয় সেটাকে ফ্লেক্স কন্টেইনার বলে এবং ফ্লেক্স কন্টেইনার এর মধ্যে যে আইটেম গুলো থাকে সেগুলোকে ফ্লেক্স আইটেম বলে।

    একটি ফ্লেক্স কন্টেইনার এর দুইটি অক্ষ থাকে একটি হচ্ছে মেইন বা প্রধান অক্ষ এবং আরেকটি হচ্ছে ক্রস অক্ষ। এক নজরে একটি চিত্রের সাহায্যে ফ্লেক্স লেআউট দেখে নেয়া যাক।
    FlexlayoutAI.png



    ফ্লেক্সবক্স কন্টেইনার বিস্তারিতঃ

    কোন একটি এইচটিএমএল এলেমেন্ট কে display:flex প্রপার্টি বলে দিলেই এটি ফ্লেক্স কন্টেইনার হয়ে যায় এবং ফ্লেক্স কন্টেইনার এর সরাসরি চাইল্ড এলেমেন্ট গুলো ফ্লেক্স আইটেম হয়ে যায়। সাথে সাথে ফ্লেক্স আইটেম গুলো বাম দিক থেকে ডান দিক বরাবর অবস্থান করে।

    .container{
            display: flex;
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    ফ্লেক্স কন্টেইনার বোঝার জন্য নিচের চিত্র টি দেখুন।
    FlexContainer.png

    flex-direction:
    ফ্লেক্স আইটেম গুলোকে x-axis অথবা y-axis বরাবর অগ্রসর করানোর জন্য flex-direction প্রপার্টি ব্যবহার করা হয়। flex-direction প্রপার্টির ৪ ধরনের মান ব্যবহার করা যায়। এগুলো হল নিম্নরূপ।

    .container{
            display: flex;
            flex-direction: row || row-reverse || column || column-reverse;
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    flexdirectionfigure.png

    • flex-direction: row; ফ্লেক্স আইটেম গুলো বাম থেকে ডানে অবস্থান করবে।
    • flex-direction: row-reverse; ফ্লেক্স আইটেম গুলো ডান থেকে বামে অবস্থান করবে।
    • flex-direction: column; ফ্লেক্স আইটেম গুলো উপর থেকে নিচে y-axis বরাবর অবস্থান করবে।
    • flex-direction: column-reverse; ফ্লেক্স আইটেম গুলো নিচে থেকে উপরে y-axis বরাবর অবস্থান করবে।

    flex-wrap:
    বাই ডিফল্ট ফ্লেক্স আইটেম গুলো nowrap করা থাকে যে কারণে আইটেম গুলো একটি লাইনে দেখায়। এটির একটা সমস্যা হল ডিভাইস উইড্থ ছোট হলে যে কয়েকটা আইটেম ডিভাইস এ দেখানো সম্ভব সেগুলো দেখাবে এবং অন্য আইটেম গুলোকে শেষের দিক থেকে দেখা যাবে না কারণ সেগুলো overflow হয়ে যাবে। flex-wrap ব্যবহার করে খুব সহজেই এই বেহেভিওর পরিবর্তন করা যায়। flex-wrap প্রপার্টির ৩ ধরনের মান ব্যবহার করা যায়। এগুলো হল নিম্নরূপ।

    .container{
            display: flex;
            flex-wrap: nowrap || wrap || wrap-reverse;
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    flexwrap.png

    • flex-wrap: nowrap; সকল ফ্লেক্স আইটেম গুলো একটি লাইন এ অবস্থান করবে।
    • flex-wrap: wrap; প্রয়োজন অনুসারে ফ্লেক্স আইটেম গুলো উপর থেকে নিচে wrap হবে (এটি ডিভাইস উইড্থ এর সাথে রেস্পন্সিভলি পরিবর্তন হয়)।
    • flex-wrap: wrap-reverse; প্রয়োজন অনুসারে ফ্লেক্স আইটেম গুলো বিপরীত ভাবে wrap হবে (এটি ডিভাইস উইড্থ এর সাথে রেস্পন্সিভলি পরিবর্তন হয়)।

    flex-flow:
    flex-direction এবং flex-wrap এর শর্টহ্যান্ড হল flex-flow। প্রথমে লিখতে হবে flex-direction এবং পরে লিখতে হবে flex-wrap প্রপার্টি। flex-flow এর ডিফল্ট মান হলঃ flex-flow: row nowrap;

    .container{
            display: flex;
            flex-flow: row wrap;
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    justify-content:
    justify-content ব্যবহার করে ফ্লেক্স আইটেম গুলোকে প্রধান অক্ষ বরাবর সাজানো যায়। justify-content প্রপার্টির ৬ ধরনের মান ব্যবহার করা যায়। এগুলো হল নিম্নরূপ।

    .container{
            display: flex;
            justify-content: flex-start || flex-end || center || space-between || space-around || space-evenly;
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    justifycontent.png

    • justify-content: flex-start; ফ্লেক্স আইটেম গুলো কন্টেইনার এর শুরু থেকে অবস্থান করবে।
    • justify-content: flex-end; ফ্লেক্স আইটেম গুলো কন্টেইনার এর শেষে থেকে অবস্থান করবে।
    • justify-content: center; ফ্লেক্স আইটেম গুলো কন্টেইনার এর কেন্দ্রে অবস্থান করবে।
    • justify-content: space-between; প্রথম ফ্লেক্স আইটেম একদম কন্টেইনার এর শুরুতে থাকবে এবং শেষ ফ্লেক্স আইটেম একদম কন্টেইনার এর শেষে থাকবে, মাঝের আইটেম গুলো নিজেদের আগে ও পরে সমান জায়গা নিয়ে অবস্থান করবে বা ছড়িয়ে যাবে।
    • justify-content: space-around; ফ্লেক্স আইটেম নিজেদের আগে ও পরে সমান জায়গা নিয়ে ছড়িয়ে যাবে। এক্ষেত্রে প্রথম আইটেম এর শুরুতে এবং শেষ আইটেম এর পরের ফাঁকা জায়গা এবং আইটেম গুলোর মাঝে ফাঁকা জায়গা সমান হয় না।
    • justify-content: space-evenly; সবগুলো ফ্লেক্স আইটেম এর আগে ও পরে সমান জায়গা থাকে। কন্টেইনার এর মোট ফাঁকা জায়গা আইটেম এর আগে ও পরে সমান ভাবে থাকে।

    align-items:
    ফ্লেক্স কন্টেইনার এর প্রত্যেকটা লাইন এর আইটেম গুলোকে উপর থেকে নিচে বরাবর align করার জন্য align-items প্রপার্টি ব্যবহার করা হয়। align-items প্রপার্টির ৫ ধরনের মান ব্যবহার করা যায়। এগুলো হল নিম্নরূপ।

    .container{
            display: flex;
            align-items: flex-start || stretch || flex-end || center || baseline;
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    alignitems.png

    • align-items: flex-start; ফ্লেক্স আইটেম গুলো প্রত্যেক লাইনের উপড়ে অবস্থান করবে।
    • align-items: stretch; একটি ফ্লেক্স কন্টেইনার এর মধ্যে যদি একটি লাইনেয় আইটেম থাকে তাহলে আইটেম গুলো পুরো কন্টেইনার এর উচ্চতা টাই নিবে আর দুই লাইন এ আইটেম থাকলে পুরো কন্টেইনার এর উচ্চতা এর অর্ধেক জায়গা নিবে।
    • align-items: flex-end; ফ্লেক্স আইটেম গুলো প্রত্যেক লাইনের নিচে অবস্থান করবে।
    • align-items: center; ফ্লেক্স আইটেম গুলো প্রত্যেক লাইনের উপর থেকে নিচ বরাবর কেন্দ্রে অবস্থান করবে।
    • align-items: baseline; ফ্লেক্স আইটেম গুলো তাদের baseline অনুসারে align হবে।

    align-content:
    ফ্লেক্স কন্টেইনার এর প্রত্যেকটা লাইনকে আলাদা আলাদা ভাবে চিন্তা না করে একটি কন্টেন্ট হিসাবে চিন্তা করে ক্রস আক্সিস বরাবর align করার জন্য align-content ব্যবহার করা হয়। এটি অনেকটা justify-content এর মত বলতে পারেন। justify-content মেইন আক্সিস বরাবর কাজ করে অপরদিকে align-content ক্রস আক্সিস বরাবর কাজ করে। align-content প্রপার্টির ৭ ধরনের মান ব্যবহার করা যায়। এগুলো হল নিম্নরূপ।

    .container{
            display: flex;
            align-content: flex-start || flex-end || center || stretch || space-between || space-around || space-evenly;
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    aligncontent.png

    • align-content: flex-start; ক্রস আক্সিস বরাবর সকল ফ্লেক্স আইটেম গুলো কন্টেইনার এর শুরু থেকে অবস্থান করবে।
    • align-content: flex-end; ক্রস আক্সিস বরাবর সকল ফ্লেক্স আইটেম গুলো কন্টেইনার এর শেষে থেকে অবস্থান করবে।
    • align-content: center; ক্রস আক্সিস বরাবর সকল ফ্লেক্স আইটেম গুলো কন্টেইনার এর কেন্দ্রে অবস্থান করবে।
    • align-content: stretch; ক্রস আক্সিস বরাবর সকল ফ্লেক্স আইটেম গুলো stretch হয়ে যায়।
    • align-content: space-between; ক্রস আক্সিস বরাবর প্রথম ফ্লেক্স আইটেম একদম কন্টেইনার এর শুরুতে থাকবে এবং শেষ ফ্লেক্স আইটেম একদম কন্টেইনার এর শেষে থাকবে, মাঝের আইটেম গুলো নিজেদের আগে ও পরে সমান জায়গা নিয়ে অবস্থান করবে বা ছড়িয়ে যাবে।
    • align-content: space-around; ক্রস আক্সিস বরাবর ফ্লেক্স আইটেম নিজেদের আগে ও পরে সমান জায়গা নিয়ে ছড়িয়ে যাবে। এক্ষেত্রে প্রথম আইটেম এর শুরুতে এবং শেষ আইটেম এর পরের ফাঁকা জায়গা এবং আইটেম গুলোর মাঝে ফাঁকা জায়গা সমান হয় না।
    • align-content: space-evenly; ক্রস আক্সিস বরাবর সবগুলো ফ্লেক্স আইটেম এর আগে ও পরে সমান জায়গা থাকে। কন্টেইনার এর মোট ফাঁকা জায়গা আইটেম এর আগে ও পরে সমান ভাবে থাকে।

    gap, row-gap, column-gap:
    ফ্লেক্স আইটেম গুলোর মধ্যে ফাঁকা জায়গা রাখার জন্য gap প্রপার্টি ব্যবহার করা হয়।
    ফ্লেক্স আইটেম গুলোর মধ্যে মেইন আক্সিস বরাবর ফাঁকা জায়গা রাখার জন্য row-gap প্রপার্টি ব্যবহার করা হয়।
    ফ্লেক্স আইটেম গুলোর মধ্যে ক্রস আক্সিস বরাবর ফাঁকা জায়গা রাখার জন্য column-gap প্রপার্টি ব্যবহার করা হয়।

    .container{
            display: flex;
            gap: 24px;
              /* gap: 24px 30px; */ /* row-gap column-gap */
              /* row-gap: 24px; */
              /* column-gap: 24px; */
    }
    
    Enter fullscreen mode

    Exit fullscreen mode



    ফ্লেক্সবক্স আইটেম বিস্তারিতঃ

    ফ্লেক্স কন্টেইনার এর সরাসরি চাইল্ড এলেমেন্ট গুলোই ফ্লেক্স আইটেম।
    flexitems.png

    order:
    ফ্লেক্স আইটেম গুলোর ডিফল্ট অর্ডার হিসাবে ০ থাকে। এইচটিএমএল কোড অনুযায়ী আইটেম গুলোর অর্ডার থাকে কিন্তু আলাদা করে কোন একটি আইটেম এর অর্ডার এর মান নির্ধারণ করে দিলে সেই অর্ডার অনুযায়ী আইটেম গুলো অবস্থান করবে।

    .container{
            display: flex;
    }
    /* অর্ডার পরিবর্তন করার কোড */
    .item{
            order: 2;
    }
    .item-1{
            order: 1;
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    Order.png

    flex-grow:
    মেইন আক্সিস বরাবর একটি লাইনে যতগুলো আইটেম থাকে সেই আইটেম গুলো ছাড়া যদি কোন ফাঁকা জায়গা থাকে তাহলে সেই ফাঁকা জায়গা সবগুলো আইটেম এর মধ্যে সমান ভাবে ছড়িয়ে দেওয়া অথবা কোন একটি নির্দিষ্ট আইটেম এর মধ্যে ছড়িয়ে দেওয়ার জন্য flex-grow ব্যবহার হয়। সবগুলো আইটেম এর মধ্যে ফাঁকা জায়গা সমানভাবে ছড়িয়ে দেওয়ার জন্য সবগুলো আইটেম কে flex-grow: 1; দিতে হয়। এক্ষেত্রে আইটেম গুলোর উইড্থ নির্ধারণ করা থাকলেও যখন ফাঁকা জায়গা পাবে সেই ফাঁকা যায়গা নিজেদের মধ্যে নিয়ে নিবে এবং সমান ভাবে আকৃতি পরিবর্তন করবে। অথবা কোন একটি নির্দিষ্ট আইটেম কে টার্গেট করেও flex-grow অ্যাপ্লাই করা যায়। ডিফল্ট flex-grow এর মান থাকে ০।

            display: flex;
    }
    .item-3{
            flex-grow: 1;
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    flexGrow.png

    flex-shrink:
    flex-shrink ঠিক flex-grow এর উল্টো। ব্রাউজার উইন্ডো ছোট করার সাথে সাথে আইটেম গুলো shrink করবে কিনা সেটা নির্ভর করে flex-shrink এর উপর। ডিফল্ট মান থাকে ১ যার কারণে আইটেম গুলো shrink করে কিন্তু shrink এর মান ০ করে দিলে রেস্পন্সিভনেস থাকবে না এবং আইটেম গুলো ব্রাউজার উইন্ডো এর বাহিরে চলে যাবে।

    .item-1 {
      flex-shrink: 0; /* ডিফল্ট 1 */
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    flex-basis:
    flex-basis হল কোন একটি আইটেম এর মিনিমাম কত উইড্থ হবে সেইটা নির্ধারণ করে দেওয়া। এটা অনেকটা min-width প্রপার্টি এর মত কিন্তু flex-basis এর সবচেয়ে বড় সুবিধা হল ব্রাউজার উইন্ডো উইড্থ যদি আইটেম গুলোর flex-basis এর মোট মানের তুলনায় ছোট হয় তাহলে আইটেম overflow না হয়ে রেস্পন্সিভলি উইড্থ টা কমিয়ে নিবে।

    .item {
      flex-basis: 500px; /* ডিফল্ট auto */
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    flex:
    flex-grow, flex-shrink এবং flex-basis একসাথে লেখার জন্য আমরা flex শর্টহ্যান্ড টা ব্যবহার করতে পারি।

    .item {
      flex: flex-grow flex-shrink flex-basis;
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    align-self:
    align-self প্রপার্টি ব্যবহার করে কোন একটা নির্দিষ্ট ফ্লেক্স আইটেম এর ডিফল্ট এলাইনমেন্ট ওভাররাইড করা যায়। align-items এর মতো align-self এ একয় রকম মান (stretch, center, flex-start, flex-end, baseline) ব্যবহার করা যায় এবং একই লজিক এ কাজ করে। তবে align-self এর ডিফল্ট মান হল auto।

    .item-2 {
      align-self: auto || flex-start || flex-end || center || baseline || stretch;
    }
    
    Enter fullscreen mode

    Exit fullscreen mode

    alignself.png

  • ডেভেলপারদের নিত্যদিনের সঙ্গী মার্কডাউন

    ডেভেলপারদের নিত্যদিনের সঙ্গী মার্কডাউন

    আপনি যদি একজন ডেভেলপার হয়ে থাকেন তাহলে নিশ্চয়ই আপনি জানে যে, গিট বা গিটহাব কি জিনিস। সংক্ষেপে এটা একটি ভার্সন কন্ট্রোলিং সিস্টেম। যখন আমরা কোন প্রোজেক্ট গিটহাবে ভার্সন কন্ট্রোল করি তখন প্রত্যেকটা রিপোজিটোরিতে একটা কমন ফাইল থাকে যার নাম README.md। README.md ফাইলে মূলত প্রোজেক্ট এর একটা সংক্ষিপ্ত বিবরণ থাকে, যেমনঃ প্রোজেক্ট কেন করা হয়েছে, কি কি টেকনোলজি ব্যবহার করা হয়েছে, কিভাবে ইন্সটল করতে হবে, ডেমো লিঙ্ক ইত্যাদি। আর এগুলোকে যদি আপনি নিজের মত করে ফরম্যাটিং করতে চান যেমনঃ টাইটেল বানানো, লেখা বোল্ড করা, লিঙ্ক করা, ইমেজ দেখানো ইত্যাদি, তাহলে আপনাকে অবশ্যই মার্কডাউন সম্পর্কে জানতে হবে।

    আবার আপনি যদি আপনার গিটহাব প্রোফাইল পেইজ টা পিন করা রিপোজিটোরির পরিবর্তে সুন্দর করে উপস্থাপন করতে চান, সুন্দর একটা প্রোফাইল রিডমি তৈরি করতে চান তাহলে আপনাকে অবশ্যই মার্কডাউন ভালো ভাবে জানতে হবে। তাহলে চলুন দেরি না করে আমরা মার্কডাউন শেখা শুরু করি।



    মার্কডাউন কিঃ

    মার্কডাউন হল একটি লাইটওয়েট মার্কআপ ল্যাঙ্গুয়েজ যার মাধ্যমে লেখাকে ফরম্যাটিং করা হয়। বর্তমান সময়ে এটি খুবই জনপ্রিয় মার্কআপ ল্যাঙ্গুয়েজ।

    জনপ্রিয় ওয়েবসাইট যেমনঃ GitHub, Reddit, Dev.to মার্কডাউন সাপোর্ট করে। গিটহাব সম্পর্কে আমি ইতিমধ্যে বলেছি। Dev.to হল ডেভেলপার কমিউনিটি, এখানে আপনি চাইলেই টেক ব্লগ লিখতে পারেন তবে আপনাকে এখানে লেখার জন্য মার্কডাউন জানা থাকলে আপনার খুবই সুবিধা হবে। আরেকটা বিষয় না বললেই নয় সেইটা হলঃ আপনি এখন যে প্লাটফর্ম এ লেখাটি পড়ছেন, হা আপনি ঠিক ধরেছেন আমি টেকডাইরির কথা বলছি এখানে ব্লগ লেখার জন্য যে এডিটর ব্যবহার করা হয়েছে এটিও মার্কডাউন সাপোর্ট করে আর আমি এখন এই সুবিধাটি ব্যবহার করেই লিখছি 😊।



    কেন মার্কডাউন ব্যবহার করবেন?

    WYSIWYG এডিটর এর পরিবর্তে মার্কডাউন সাপোর্ট করে এমন এডিটর ব্যবহার দিন দিন বেড়েই যাচ্ছে। আপনি হয়তো ভাবছেন কেন সবাই WYSIWYG এডিটর এর পরিবর্তে মার্কডাউন ব্যবহার করে, এটার বেশ কিছু কারণ রয়েছে। চলুন আমরা কারণগুলো দেখিঃ

    • মার্কডাউন এখন প্রায় সব জায়গাই ব্যাবহৃত হচ্ছে। মার্কডাউন ব্যবহার করে অনেক কিছু তৈরি করা হচ্ছে যেমনঃ ওয়েবসাইট, ডকুমেন্ট, নোট, বই, প্রেজেন্টেশান, ইমেইল মেসেজ এবং টেক ডকুমেন্ট।
    • মার্কডাউন পোর্টেবল এবং মার্কডাউনে ফরম্যাট করা টেক্সট ভার্চুয়ালি যেকোনো অ্যাপ্লিকেশানে ওপেন করা যায়।
    • আপনি যেকোনো ডিভাইসে অথবা অপারেটিং সিস্টেমে মার্কডাউন তৈরি করতে পারবেন।
    • আপনি ভবিষ্যতে যদি এমন সিদ্ধান্ত নেন যে মার্কডাউন ব্যবহার করবেন না তার পরও আপনি যেকোনো টেক্সট এডিটর অ্যাপ্লিকেশান ব্যবহার করে মার্কডাউনে ফরম্যাট করা টেক্সট পড়তে পারবেন খুব সহজে।

    আরেকটি মজার বিষয় যে, এইচটিএমএল এর কোড মার্কডাউনে কাজ করে । এতো এতো সুবিধা আসলে মার্কডাউনের জনপ্রিয়তা দিন দিন বাড়িয়ে দিয়েছে বা এখনো দিচ্ছে।



    মার্কডাউন কিভাবে কাজ করে?

    markdownflowchart

    ইমেজ উৎসঃ মার্কডাউন



    মার্কডাউন নিম্নক্ত ৪টি ধাপে কাজ করেঃ

    • প্রথমে মার্কডাউন ফাইল তৈরি করতে হবে। ফাইল ফরম্যাট হবে .md।
    • মার্কডাউন ফাইলটিকে মার্কডাউন অ্যাপ্লিকেশানে ওপেন করতে হবে।
    • মার্কডাউন অ্যাপ্লিকেশান মার্কডাউন ফাইলটিকে প্রসেস করে এইচটিএমএল ফাইলে কনভার্ট করবে।
    • তারপর আমরা ফাইলটিকে ব্রাউজার এ দেখতে পাবো।

    তবে চিন্তার কোন কারণ নেই আমাদেরকে এত গুলো প্রসেসের মধ্যে দিয়ে যেতে হবে না। আমি এখানে মার্কডাউন লেখার জন্য Dillinger এডিটর ব্যবহার করবো। Dillinger এডিটর ব্যবহার করে আপনি একপাশে মার্কডাউন কোড লিখবেন এবং অপরপাশে আউটপুট দেখতে পাবেন। আপনি চাইলে Visual Studio Code এডিটর ব্যবহার করে মার্কডাউন কোড লিখতে পারেন।



    মার্কডাউন বিস্তারিতঃ

    চলুন জেনে নেয়া যাক কিভাবে মার্কডাউন ব্যবহার করে টেক্সট ফরম্যাট করা যায়।

    হেডিংঃ
    আশা করি এইচটিএমএল হেডিং ট্যাগ সম্পর্কে আপনারা কমবেশি সবাই জানেন। এইচটিএমএল ফাইলে হেড ট্যাগ গুলো ব্যবহার করে আমরা টাইটেল তৈরি করতে পারি। এইচটিএমএলে আমরা H1 থেকে H6 (ক্রমান্বয়ে বড় থেকে ছোট) পর্যন্ত ৬টা ট্যাগ পাই টাইটেল লেখার জন্য। মার্কডাউন ব্যবহার করেও আমরা এইচটিএমএল এর মত হেডিং লিখতে পারি আরও সহজে। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    Markdown Heading

    লেখা বোল্ড বা মোটা করাঃ
    মার্কডাউন ব্যবহার করে কোন লেখাকে বোল্ড বা মোটা করার জন্য লেখাটির আগে ও পরে ফাঁকা জায়গা ব্যাতিত ২টা করে এস্টেরিস্ক বা স্টার (**) চিহ্ন দিতে হবে। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    Markdown Bold

    লেখা ইটালিক করাঃ
    মার্কডাউন ব্যবহার করে কোন লেখাকে ইটালিক করার জন্য লেখাটির আগে ও পরে ফাঁকা জায়গা ব্যাতিত ১টা করে এস্টেরিস্ক বা স্টার (*) চিহ্ন দিতে হবে। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    Italic Markdown

    লেখা Blockquote করাঃ
    মার্কডাউন ব্যবহার করে খুব সহজে Blockquote তৈরি করা যায়। কোন লেখাকে মার্কডাউন ব্যবহার করে Blockquote করার জন্য লেখাটির আগে > এই সাইন তা দিতে হয়। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    Markdown Blockquote

    অর্ডার লিস্ট তৈরি করাঃ
    মার্কডাউন ব্যবহার করে খুব সহজে আমরা অর্ডার লিস্ট তৈরি করতে পারি। অর্ডার লিস্ট তৈরি করার জন্য প্রত্যেক লাইন এর শুরুতে নাম্বার দিতে হবে। নাম্বার ক্রমানুসারে না হলেও চলবে কিন্তু শুরুটা এক নম্বর দিয়ে হওয়া উচিত। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    markdown order list

    আনঅর্ডার লিস্ট তৈরি করাঃ
    মার্কডাউন ব্যবহার করে খুব সহজে আমরা আনঅর্ডার লিস্ট তৈরি করতে পারি। আনঅর্ডার লিস্ট তৈরি করার জন্য প্রত্যেক লাইন এর শুরুতে একটি ড্যাশ (-), এস্টেরিস্ক (*), অথবা প্লাস সাইন (+) দিলেই হবে। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    Unorderd list

    হরাইজন্টাল রুল তৈরি করাঃ
    মার্কডাউন ব্যবহার করে হরাইজন্টাল রুল তৈরি করার জন্য ৩ বা ৩ এর অধিক ড্যাশ (—), এস্টেরিস্ক (***), অথবা আন্ডারস্কোর সাইন (___) দিলেই হবে। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    Horizontal Rules

    লিঙ্ক তৈরি করাঃ
    মার্কডাউন ব্যবহার করে লিঙ্ক তৈরি করা খুবই সহজ। লিঙ্ক তৈরি করার জন্য তৃতীয় ব্রাকেট এর মধ্যে টেক্সট লিখতে হবে এবং প্রথম ব্রাকেটের মধ্যে URL লিখতে হবে। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    Markdown Link

    ইমেজঃ
    মার্কডাউনে ইমেজ ব্যবহার করা খুবই সহজ। এজন্য আমাদেরকে প্রথমে এক্সক্লামেশন মার্ক দিতে হবে, তারপর তৃতীয় ব্রাকেট এর মধ্যে ইমেজ অল্টার টেক্সট লিখতে হবে এবং প্রথম ব্রাকেটের মধ্যে ইমেজ URL লিখতে হবে। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    Markdown Image

    এক লাইনে কোড লেখাঃ
    মার্কডাউন ব্যবহার করে কোন টেক্সট কে একই লাইন এ কোড হিসাবে দেখানোর জন্য লেখাটির আগে ও পরে ব্যাকটিক (`) দিতে হবে। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    markdown code

    কোড ব্লক তৈরি করাঃ
    মার্কডাউন ব্যবহার করে কোড ব্লক তৈরি করার জন্য কোডের শুরুতে ৩টা ব্যাকটিক (`) অথবা ৩টা টিলড (~~~) এবং কোড এর শেষে ৩টা ব্যাকটিক () অথবা ৩টা টিলড (~~~) দিতে হয়। আপনি চাইলে প্রোগ্রামিং ল্যাঙ্গুয়েজ সিনট্যাক্স হাইলাইট ফিচার চালু করতে পারেন। এই জন্য আপনাকে শুরুর দিক থেকে ৩টা ব্যাকটিক (“) অথবা ৩টা টিলড (~~~) এর পরে ল্যাঙ্গুয়েজ এর নাম লিখে দিতে হবে। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    Code Block Markdown

    টেবিল তৈরি করাঃ
    মার্কডাউন ব্যবহার করে টেবিল তৈরি করা যায় খুব সহজে। টেবিলের প্রত্যেক কলামের হেডার তৈরি করার জন্য ৩ বা ৩ এর অধিক হাইফেন (—) দিতে হবে। প্রত্যেক কলাম আলাদা করার জন্য একটা পাইপ (|) চিহ্ন দিতে হবে। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    Markdown table

    স্ট্রাইকথ্রুঃ
    মার্কডাউন ব্যবহার করে স্ট্রাইকথ্রু তৈরি করার জন্য লেখার শুরু এবং শেষে ২টা টিলড (~~) দিতে হবে। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    Strikethrough markdown

    টাস্ক লিস্ট তৈরি করাঃ
    মার্কডাউন ব্যবহার করে টাস্ক লিস্ট তৈরি করার জন্য লাইনের শুরুতে তৃতীয় ব্র্যাকেট এর মধ্যে ফাঁকা জায়গা রাখলে টাস্কটি আনচেক দেখাবে এবং চেক করা দেখাতে চাইলে তৃতীয় ব্র্যাকেট এর মধ্যে x লিখতে হবে। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    Markdown Tasklist

    হাইলাইট টেক্সটঃ
    মার্কডাউন ব্যবহার করে হাইলাইট টেক্সট করার জন্য টেক্সট এর শুরু এবং শেষে ২টা (==) সমান চিহ্ন দিতে হবে। উদাহরণ সরূপ নিম্নের চিত্রটি দেখুন।
    Texthighlight markdown

    ইমোজিঃ
    আপনি যদি মার্কডাউন ব্যবহার করতে চান তাহলে আপনাকে তেমন কিছুই করতে হবে না। যে ইমোজি ব্যবহার করতে চান শুধু ইমোজিটা কপি করে এনে মার্কডাউনে পেস্ট করতে হবে।

    এখানে আমি চেষ্টা করেছি মার্কডাউন নিয়ে কাজ করতে গেলে সচারচর যে বিষয় গুলো সম্পর্কে ধারনা থাকটা জরুরী সেই বিষয় গুলো নিয়ে আলোচনা করার। আপনি যদি মার্কডাউন সম্পর্কে আরও বিস্তারিত জানতে আগ্রহী হন তাহলে মার্কডাউন এর অফিসিয়াল ডকুমেন্টেশন টা দেখতে পারেন।