Skip to content

Aspect ratio selection for Facebook posts (like Instagram)#82

Merged
paulocastellano merged 8 commits into
mainfrom
69-feature-aspect-ratio-selection-for-facebook-posts-like-instagram
Jun 10, 2026
Merged

Aspect ratio selection for Facebook posts (like Instagram)#82
paulocastellano merged 8 commits into
mainfrom
69-feature-aspect-ratio-selection-for-facebook-posts-like-instagram

Conversation

@paulocastellano

Copy link
Copy Markdown
Contributor

Closes #69

What

Facebook feed posts now have the same aspect ratio selector as Instagram — 1:1, 4:5, 16:9, Original — so users control how their image is cropped before publishing, instead of leaving it to Facebook's auto-crop. This matters for accounts posting photography/exhibition content where composition matters.

Why it works this way (API analysis)

The reporter assumed the Facebook Graph API exposes aspect ratios. It doesn't for organic Page posts:

  • The Graph API Photo node (POST /{page-id}/photos) has no crop or aspect-ratio parameter — only the image source + metadata.
  • The Marketing API Image Crops feature is ads-only: "Page posts are not supported."
  • Facebook displays the photo at the native aspect ratio of the bytes it receives (within its 9:16–16:9 band).

So the only way to control the crop — exactly like Instagram already does — is to crop server-side before upload. No new Facebook API surface is involved.

How

  • CropsImageForAspectRatio (new concern) — the crop logic (download → MediaOptimizer::cropToAspectRatio → store → public URL) extracted from InstagramPublisher, with a per-publisher cropFailureException hook so each throws its own typed exception.
  • InstagramPublisher — refactored onto the concern. Behaviour identical; the existing 25 IG tests pass unchanged (the refactor's safety net).
  • FacebookPublisher — reads meta.aspect_ratio and crops single- and multi-image feed posts (stored under facebook-crops/). Reels/Stories (video) are untouched.
  • FrontendFacebookSettings shows the picker on the Feed variant (default Original → no crop, matching FB's native-ratio behaviour); ScheduleTab wires :meta/@update:meta; FacebookPreview reflects the chosen ratio (falls back to the current fill layout when Original/unset).
  • i18nposts.form.facebook.aspect.* in en / es / pt-BR.

Validation needs no change: platforms.*.meta.aspect_ratio is already platform-agnostic.

Tests

New in FacebookPublisherTest:

  • Single-image crop across 1:1 / 4:5 / 16:9 (dataset) — decodes the stored crop, asserts real dimensions, and asserts the cropped URL (facebook-crops/) is what's uploaded, not the source.
  • Multi-image — every image cropped + upload uses the crop.
  • No ratio / Original → original image uploaded, no crop written.
  • Download failure during crop → FacebookPublishException.

Full suite: 1689 passed, 2 skipped (pre-existing, font-dependent). Pint + ESLint clean.

Facebook feed posts now have the same aspect ratio selector as Instagram
(1:1, 4:5, 16:9, Original), letting users control how their image is cropped
before publishing instead of leaving it to Facebook's auto-crop.

The Facebook Graph API has no crop/aspect-ratio parameter for organic Page
photo posts (image crops are ads-only) — Facebook displays the bytes it
receives at their native ratio. So, exactly like Instagram, the crop is done
server-side before upload.

- Extract the Instagram crop logic into a shared CropsImageForAspectRatio
  concern (download -> crop -> store -> URL), with a per-publisher
  cropFailureException hook. InstagramPublisher refactored to use it
  (behaviour identical; existing tests unchanged).
- FacebookPublisher reads meta.aspect_ratio and crops single- and multi-image
  feed posts (facebook-crops/ prefix). Reels/Stories are unaffected.
- FacebookSettings: aspect ratio picker on the Feed variant (default Original
  -> no crop). ScheduleTab wires meta; FacebookPreview reflects the chosen
  ratio. Adds posts.form.facebook.aspect.* in en/es/pt-BR.

Closes #69
- CropsImageForAspectRatio: drop the per-publisher path-prefix argument; crops
  from both platforms go to a single `social-crops/` directory (the folder has
  no functional meaning — the platform fetches by URL and nothing reads it back;
  UUID filenames prevent collisions).
- Close the IG/FB test asymmetry surfaced in review: Instagram single-image crop
  now runs across 1:1/4:5/16:9 (dataset) and has a crop-download-failure test;
  Facebook gains an explicit 'original' bypass test. Both platforms now cover the
  same matrix (crop per ratio + uploaded-URL is the crop, original/no-meta
  bypass, multi-image, download-failure exception).

Follow-up tracked in #83 (orphaned crops are never pruned from storage).
- Instagram carousel and Facebook multi-image crop tests now run as datasets
  over 1:1 and 4:5, asserting each image's real cropped ratio (previously 1:1
  only) — proving the chosen ratio flows through the multi-image paths.
- Add a Facebook test that a multi-image post aborts entirely (throws
  FacebookPublishException) when one image can't be downloaded for cropping.
…abs including preview, schedule, and comments functionalities
@paulocastellano paulocastellano merged commit 693e9c9 into main Jun 10, 2026
2 checks passed
@paulocastellano paulocastellano deleted the 69-feature-aspect-ratio-selection-for-facebook-posts-like-instagram branch June 10, 2026 17:56
paulocastellano added a commit to Falconiere/trypost that referenced this pull request Jun 10, 2026
PR trypostit#82 made `meta.aspect_ratio` crop Facebook (and already Instagram) feed
images at publish time, but the API and MCP surfaces only half-supported it:
you couldn't set meta at creation, the value wasn't validated, and responses
never returned it. This closes those gaps.

- New `AspectRatio` enum is the single source of truth for the allowed ratios
  (1:1, 4:5, 16:9, original). App/API/MCP requests now validate via
  `Rule::enum(AspectRatio::class)` — an invalid ratio is rejected everywhere
  instead of silently center-cropping to square.
- API `StorePostRequest` and MCP `CreatePostTool` now accept `platforms.*.meta`;
  `CreatePost` persists it. MCP create documents `meta` in its schema.
- `Api\PostPlatformResource` now exposes `meta`, so API and MCP responses return
  the aspect_ratio (and other per-platform meta) a client set.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Aspect ratio selection for Facebook posts (like Instagram)

1 participant